diff --git a/en_US.ISO8859-1/books/handbook/advanced-networking/chapter.sgml b/en_US.ISO8859-1/books/handbook/advanced-networking/chapter.sgml index 40920ae8ae..f964e3f60b 100644 --- a/en_US.ISO8859-1/books/handbook/advanced-networking/chapter.sgml +++ b/en_US.ISO8859-1/books/handbook/advanced-networking/chapter.sgml @@ -1,6571 +1,6571 @@ Advanced Networking Synopsis This chapter will cover some of the more frequently used network services on Unix systems. We will cover how to define, setup, test and maintain all of the network services that FreeBSD utilizes. In addition, there have been example configuration files included throughout this chapter for you to benefit from. After reading this chapter, you will know: The basics of gateways and routes. How to make FreeBSD act as a bridge. How to setup a network filesystem. How to setup network booting on a diskless machine. How to setup a network information server for sharing user accounts. How to setup automatic network settings using DHCP. How to setup a domain name server. How to synchronize the time and date, and setup a time server, with the NTP protocol. How to setup network address translation. How to manage the inetd daemon. How to connect two computers via PLIP. How to setup IPv6 on a FreeBSD machine. Before reading this chapter, you should: Understand the basics of the /etc/rc scripts. Be familiar with basic network terminology. Coranth Gryphon Contributed by Gateways and Routes routing gateway subnet For one machine to be able to find another over a network, there must be a mechanism in place to describe how to get from one to the other. This is called routing. A route is a defined pair of addresses: a destination and a gateway. The pair indicates that if you are trying to get to this destination, communicate through this gateway. There are three types of destinations: individual hosts, subnets, and default. The default route is used if none of the other routes apply. We will talk a little bit more about default routes later on. There are also three types of gateways: individual hosts, interfaces (also called links), and Ethernet hardware addresses (MAC addresses). An Example To illustrate different aspects of routing, we will use the following example from netstat: &prompt.user; netstat -r Routing tables Destination Gateway Flags Refs Use Netif Expire default outside-gw UGSc 37 418 ppp0 localhost localhost UH 0 181 lo0 test0 0:e0:b5:36:cf:4f UHLW 5 63288 ed0 77 10.20.30.255 link#1 UHLW 1 2421 example.com link#1 UC 0 0 host1 0:e0:a8:37:8:1e UHLW 3 4601 lo0 host2 0:e0:a8:37:8:1e UHLW 0 5 lo0 => host2.example.com link#1 UC 0 0 224 link#1 UC 0 0 default route The first two lines specify the default route (which we will cover in the next section) and the localhost route. loopback device The interface (Netif column) that this routing table specifies to use for localhost is lo0, also known as the loopback device. This says to keep all traffic for this destination internal, rather than sending it out over the LAN, since it will only end up back where it started. Ethernet MAC address The next thing that stands out are the addresses beginning with 0:e0:. These are Ethernet hardware addresses, which are also known as MAC addresses. FreeBSD will automatically identify any hosts (test0 in the example) on the local Ethernet and add a route for that host, directly to it over the Ethernet interface, ed0. There is also a timeout (Expire column) associated with this type of route, which is used if we fail to hear from the host in a specific amount of time. When this happens, the route to this host will be automatically deleted. These hosts are identified using a mechanism known as RIP (Routing Information Protocol), which figures out routes to local hosts based upon a shortest path determination. subnet FreeBSD will also add subnet routes for the local subnet (10.20.30.255 is the broadcast address for the subnet 10.20.30, and example.com is the domain name associated with that subnet). The designation link#1 refers to the first Ethernet card in the machine. You will notice no additional interface is specified for those. Both of these groups (local network hosts and local subnets) have their routes automatically configured by a daemon called routed. If this is not run, then only routes which are statically defined (i.e. entered explicitly) will exist. The host1 line refers to our host, which it knows by Ethernet address. Since we are the sending host, FreeBSD knows to use the loopback interface (lo0) rather than sending it out over the Ethernet interface. The two host2 lines are an example of what happens when we use an &man.ifconfig.8; alias (see the section on Ethernet for reasons why we would do this). The => symbol after the lo0 interface says that not only are we using the loopback (since this address also refers to the local host), but specifically it is an alias. Such routes only show up on the host that supports the alias; all other hosts on the local network will simply have a link#1 line for such routes. The final line (destination subnet 224) deals with multicasting, which will be covered in another section. Finally, various attributes of each route can be seen in the Flags column. Below is a short table of some of these flags and their meanings: U Up: The route is active. H Host: The route destination is a single host. G Gateway: Send anything for this destination on to this remote system, which will figure out from there where to send it. S Static: This route was configured manually, not automatically generated by the system. C Clone: Generates a new route based upon this route for machines we connect to. This type of route is normally used for local networks. W WasCloned: Indicated a route that was auto-configured based upon a local area network (Clone) route. L Link: Route involves references to Ethernet hardware. Default Routes default route When the local system needs to make a connection to a remote host, it checks the routing table to determine if a known path exists. If the remote host falls into a subnet that we know how to reach (Cloned routes), then the system checks to see if it can connect along that interface. If all known paths fail, the system has one last option: the default route. This route is a special type of gateway route (usually the only one present in the system), and is always marked with a c in the flags field. For hosts on a local area network, this gateway is set to whatever machine has a direct connection to the outside world (whether via PPP link, DSL, cable modem, T1, or another network interface). If you are configuring the default route for a machine which itself is functioning as the gateway to the outside world, then the default route will be the gateway machine at your Internet Service Provider's (ISP) site. Let us look at an example of default routes. This is a common configuration: [Local2] <--ether--> [Local1] <--PPP--> [ISP-Serv] <--ether--> [T1-GW] The hosts Local1 and Local2 are at your site. Local1 is connected to an ISP via a dial up PPP connection. This PPP server computer is connected through a local area network to another gateway computer through an external interface to the ISPs Internet feed. The default routes for each of your machines will be: Host Default Gateway Interface Local2 Local1 Ethernet Local1 T1-GW PPP A common question is Why (or how) would we set the T1-GW to be the default gateway for Local1, rather than the ISP server it is connected to?. Remember, since the PPP interface is using an address on the ISP's local network for your side of the connection, routes for any other machines on the ISP's local network will be automatically generated. Hence, you will already know how to reach the T1-GW machine, so there is no need for the intermediate step of sending traffic to the ISP server. As a final note, it is common to use the address X.X.X.1 as the gateway address for your local network. So (using the same example), if your local class-C address space was 10.20.30 and your ISP was using 10.9.9 then the default routes would be: Host Default Route Local2 (10.20.30.2) Local1 (10.20.30.1) Local1 (10.20.30.1, 10.9.9.30) T1-GW (10.9.9.1) Dual Homed Hosts dual homed hosts There is one other type of configuration that we should cover, and that is a host that sits on two different networks. Technically, any machine functioning as a gateway (in the example above, using a PPP connection) counts as a dual-homed host. But the term is really only used to refer to a machine that sits on two local-area networks. In one case, the machine has two Ethernet cards, each having an address on the separate subnets. Alternately, the machine may only have one Ethernet card, and be using &man.ifconfig.8; aliasing. The former is used if two physically separate Ethernet networks are in use, the latter if there is one physical network segment, but two logically separate subnets. Either way, routing tables are set up so that each subnet knows that this machine is the defined gateway (inbound route) to the other subnet. This configuration, with the machine acting as a router between the two subnets, is often used when we need to implement packet filtering or firewall security in either or both directions. If you want this machine to actually forward packets between the two interfaces, you need to tell FreeBSD to enable this ability. Building a Router router A network router is simply a system that forwards packets from one interface to another. Internet standards and good engineering practice prevent the FreeBSD Project from enabling this by default in FreeBSD. You can enable this feature by changing the following variable to YES in &man.rc.conf.5;: gateway_enable=YES # Set to YES if this host will be a gateway This option will set the &man.sysctl.8; variable net.inet.ip.forwarding to 1. If you should need to stop routing temporarily, you can reset this to 0 temporarily. Your new router will need routes to know where to send the traffic. If your network is simple enough you can use static routes. FreeBSD also comes with the standard BSD routing daemon &man.routed.8;, which speaks RIP (both version 1 and version 2) and IRDP. For more complex situations you may want to try net/gated. Even when FreeBSD is configured in this way, it does not completely comply with the Internet standard requirements for routers. It comes close enough for ordinary use, however. Routing Propagation routing propagation We have already talked about how we define our routes to the outside world, but not about how the outside world finds us. We already know that routing tables can be set up so that all traffic for a particular address space (in our examples, a class-C subnet) can be sent to a particular host on that network, which will forward the packets inbound. When you get an address space assigned to your site, your service provider will set up their routing tables so that all traffic for your subnet will be sent down your PPP link to your site. But how do sites across the country know to send to your ISP? There is a system (much like the distributed DNS information) that keeps track of all assigned address-spaces, and defines their point of connection to the Internet Backbone. The Backbone are the main trunk lines that carry Internet traffic across the country, and around the world. Each backbone machine has a copy of a master set of tables, which direct traffic for a particular network to a specific backbone carrier, and from there down the chain of service providers until it reaches your network. It is the task of your service provider to advertise to the backbone sites that they are the point of connection (and thus the path inward) for your site. This is known as route propagation. Troubleshooting traceroute Sometimes, there is a problem with routing propagation, and some sites are unable to connect to you. Perhaps the most useful command for trying to figure out where routing is breaking down is the &man.traceroute.8; command. It is equally useful if you cannot seem to make a connection to a remote machine (i.e. &man.ping.8; fails). The &man.traceroute.8; command is run with the name of the remote host you are trying to connect to. It will show the gateway hosts along the path of the attempt, eventually either reaching the target host, or terminating because of a lack of connection. For more information, see the manual page for &man.traceroute.8;. Eric Anderson Written by Wireless Introduction It can be very useful to be able to use a computer without the annoyance of having a network cable attached at all times. FreeBSD can be used as a wireless client, and even as a wireless access point. Wireless background There are two different ways to configure 802.11 wireless devices: BSS and IBSS. BSS mode BSS mode is the mode that typically is used. BSS mode is also called infrastructure mode. In this mode, a number of wireless access points are connected to a wired network. Each wireless network has its own name. This name is called the SSID of the network. Wireless clients connect to these wireless access points. The IEEE 802.11 standard defins the protocol that wireless networks use to connect. A wireless client can be tied to a specific network, when a SSID is set. A wireless client can also attach to any network by not excplicitly setting a SSID. IBSS Mode IBSS mode, also called ad-hoc mode, is designed for point to point connections. There are actually two types of ad-hoc mode. One is IBSS mode, also called ad-hoc or IEEE ad-hoc mode. This mode is defined by the IEEE 802.11 standards. The second is called demo ad-hoc mode or Lucent ad-hoc mode (and sometimes confusingly ad-hoc mode). This is the old, pre-802.11 ad-hoc mode and should only be used for legacy installations. Infrastructure mode Access Points Access points are wireless networking devices that allow one or more wireless clients to use the device as a central hub. When using an access point, all clients communicate through the access point. Multiple access points are often used to cover a complete area such as a house, business, or park with a wireless network. Access points typically have multiple network connections: the wireless card, and one or more wired ethernet adapters for connection to the rest of the network. Access points can either be purchased prebuilt, or you can build your own with FreeBSD and a supported wireless card. Several vendors make wireless access points and wireless cards with various features. Building a FreeBSD Access Point Requirements In order to set up a wireless access point with FreeBSD, you need to have a compatible wireless card. Currently, only cards with the Prism chipset are supported. You will also need a wired network card that is supported by FreeBSD (this should not be difficult to find, FreeBSD supports a lot of different devices). For this guide, we will assume you want to &man.bridge.4; all traffic between the wireless device and the network attached to the wired network card. The hostap functionality that FreeBSD uses to implement the access point works best with certain versions of firmware. Prism 2 cards should use firmware version 1.3.4 or newer. Prism 2.5 and Prism 3 cards should use firmware 1.4.9. Older versions of the firmware way or may not function correctly. At this time, the only way to update cards is with windows firmware update utilities available from your card's manufacturer. Setting it up First, make sure your system can see the wireless card: &prompt.root; ifconfig -a wi0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500 inet6 fe80::202:2dff:fe2d:c938%wi0 prefixlen 64 scopeid 0x7 inet 0.0.0.0 netmask 0xff000000 broadcast 255.255.255.255 ether 00:09:2d:2d:c9:50 media: IEEE 802.11 Wireless Ethernet autoselect (DS/2Mbps) status: no carrier ssid "" stationname "FreeBSD Wireless node" channel 10 authmode OPEN powersavemode OFF powersavesleep 100 wepmode OFF weptxkey 1 Do not worry about the details now, just make sure it shows you something to indicate you have a wireless card installed. Next, you will need to load a module in order to get the bridging part of FreeBSD ready for the access point. In order to load the &man.bridge.4; module, simply run the following command: &prompt.root; kldload bridge It should not have produced any errors when loading the module. If it did, you may need to compile the &man.bridge.4; code into your kernel. The Bridging section of the handbook should be able to help you accomplish that task. Now that you have the bridging stuff done, we need to tell the FreeBSD kernel which interfaces to bridge together. We do that by using &man.sysctl.8;: &prompt.root; sysctl net.link.ether.bridge=1 &prompt.root; sysctl net.link.ether.bridge_cfg="wi0 xl0" &prompt.root; sysctl net.inet.ip.forwarding=1 Now it is time for the wireless card setup. The following command will set the card into an access point: &prompt.root; ifconfig wi0 ssid my_net channel 11 media DS/11Mbps mediaopt hostap up stationname "FreeBSD AP" The &man.ifconfig.8; line brings the wi0 interface up, sets its SSID to my_net, and sets the station name to FreeBSD AP. The sets the card into 11Mbps mode and is needed for any to take effect. The option places the interface into access point mode. The option sets the 802.11b channel to use. The &man.wicontrol.8; man page has valid channel options for your regulatory domain. Now you should have a complete functioning access point up and running. You are encouraged to read &man.wicontrol.8;, &man.ifconfig.8;, and &man.wi.4; for further information. It is also suggested that you read the section on encryption that follows. Status information Once the access point is configured and operational, operators will want to see the clients that are associated with the access point. At any time, the operator may type: &prompt.root; wicontrol -l 1 station: 00:09:b7:7b:9d:16 asid=04c0, flags=3<ASSOC,AUTH>, caps=1<ESS>, rates=f<1M,2M,5.5M,11M>, sig=38/15 This shows that there's one station associated, along with its parameters. The signal indicated should be used as a realative indication of strength only. Its translation to dBm or other units varies between different firmware revisions. Clients A wireless client is a system that accesses an access point or another client directly. Typically, wireless clients only have one network device, the wireless networking card. There are a few different ways to configure a wireless client. These are based on the different wireless modes, generally BSS (infrastructure mode, which requires an access point), and IBSS (ad-hoc, or peer-to-peer mode). In our example, we will use the most popular of the two, BSS mode, to talk to an access point. Requirements There is only one real requirement for setting up FreeBSD as a wireless client. You will need a wireless card that is supported by FreeBSD. Setting Up A Wireless FreeBSD Client You will need to know a few things about the wireless network you are joining before you start. In this example, we are joining a network that has a name of my_net, and encryption turned off. Note: In this example, we are not using encryption, which is a dangerous situation. In the next section, you will learn how to turn on encryption, and why it is important to do so, and why some encryption technologies still do not completely protect you. Make sure your card is recognized by FreeBSD: &prompt.root; ifconfig -a wi0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500 inet6 fe80::202:2dff:fe2d:c938%wi0 prefixlen 64 scopeid 0x7 inet 0.0.0.0 netmask 0xff000000 broadcast 255.255.255.255 ether 00:09:2d:2d:c9:50 media: IEEE 802.11 Wireless Ethernet autoselect (DS/2Mbps) status: no carrier ssid "" stationname "FreeBSD Wireless node" channel 10 authmode OPEN powersavemode OFF powersavesleep 100 wepmode OFF weptxkey 1 Now, we will set the card to the correct settings for our network: &prompt.root; ifconfig wi0 inet 192.168.0.20 netmask 255.255.255.0 ssid my_net Replace 192.168.0.20 and 255.255.255.0 with a valid IP address and netmask on your wired network. Remember, our access point is bridging the data between the wireless network, and the wired network, so it will appear to the other devices on your network that you are on the wired network just as they are. Once you have done that, you should be able to ping hosts on the wired network just as if you were connected using a standard wired connection. If you are experiencing problems with your wireless connection, check to make sure that your are associated (connected) to the access point: &prompt.root; ifconfig wi0 should return some information, and you should see: status: associated If it does not show associated, then you may be out of range of the access point, do not have encryption on, or possibly have a configuration problem. Encryption Encryption on a wireless network is important because you no longer have the ability to keep the network contained in a well protected area. Your wireless data will be broadcast across your entire neighborhood, so anyone who cares to read it can. This is where encryption comes in. By encrypting the data that is sent over the airwaves, you make it much more difficult for any interested party to grab your data right out of the air. The two most common ways to encrypt the data between your client and the access point, are WEP, and &man.ipsec.4;. WEP WEP is an abbreviation for Wired Equivalency Protocol. WEP is an attempt to make wireless networks as safe and secure as a wired network. Unfortunately, it has been cracked, and is fairly trivial to break. This also means it is not something to rely on when it comes to encrypting sensitive data. It is better than nothing, so use the following to turn on WEP on your new FreeBSD access point: &prompt.root; ifconfig wi0 inet up ssid my_net wepmode on wepkey 0x1234567890 media DS/11Mbps mediaopt hostap And you can turn on WEP on a client with this command: &prompt.root; ifconfig wi0 inet 192.168.0.20 netmask 255.255.255.0 ssid my_net wepmode on wepkey 0x1234567890 Note that you should replace the 0x1234567890 with a more unique key. IPsec &man.ipsec.4; is a much more robust and powerful tool for encrypting data across a network. This is definitely the preferred way to encrypt wireless data over a network. You can read more about &man.ipsec.4; security and how to implement it in the IPsec section of the handbook. Tools There are a small number of tools available for use in debugging and setting up your wireless network, and here we will attempt to describe some of them and what they do. <application>bsd-airtools</application> The bsd-airtools package is a complete toolset that includes wireless auditing tools for WEP key cracking, access point detection, etc. The bsd-airtools utilities can be installed from the net/bsd-airtools port. Information on installing ports can be found in of the handbook. The program dstumbler is the packaged tool that allows for access point discovery and signal to noise ratio graphing. If you are having a hard time getting your access point up and running, dstumbler may help you get started. To test your wireless network security, you may choose to use dweputils (dwepcrack, dwepdump and dwepkeygen) to help you determine if WEP is the right solution to your wireless security needs. wicontrol, ancontrol, raycontrol These are the tools you use to control how your wireless card behaves on the wireless network. In the examples above, we have chosen to use &man.wicontrol.8;, since our wireless card is a wi0 interface. If you had a Cisco wireless device, it would come up as an0, and therefore you would use &man.ancontrol.8;. ifconfig &man.ifconfig.8; can be used to do many of the same options as &man.wicontrol.8;, however it does lack a few options. Check &man.ifconfig.8; for command line parameters and options. Supported Cards Access Points The only cards that are currently supported for BSS (as an access point) mode are devices based on the Prism 2, 2.5, or 3 chipsets. For a complete list, look at &man.wi.4;. Clients Almost all 802.11b wireless cards are currently supported under FreeBSD. Most cards based on Prism, Spectrum24, Hermes, Aironet, and Raylink will work as a wireless network card in IBSS (ad-hoc, peer-to-peer, and BSS) mode. Steve Peterson Written by Bridging Introduction IP subnet bridge It is sometimes useful to divide one physical network (such as an Ethernet segment) into two separate network segments without having to create IP subnets and use a router to connect the segments together. A device that connects two networks together in this fashion is called a bridge. A FreeBSD system with two network interface cards can act as a bridge. The bridge works by learning the MAC layer addresses (Ethernet addresses) of the devices on each of its network interfaces. It forwards traffic between two networks only when its source and destination are on different networks. In many respects, a bridge is like an Ethernet switch with very few ports. Situations Where Bridging Is Appropriate There are two common situations in which a bridge is used today. High Traffic on a Segment Situation one is where your physical network segment is overloaded with traffic, but you do not want for whatever reason to subnet the network and interconnect the subnets with a router. Let us consider an example of a newspaper where the Editorial and Production departments are on the same subnetwork. The Editorial users all use server A for file service, and the Production users are on server B. An Ethernet is used to connect all users together, and high loads on the network are slowing things down. If the Editorial users could be segregated on one network segment and the Production users on another, the two network segments could be connected with a bridge. Only the network traffic destined for interfaces on the other side of the bridge would be sent to the other network, reducing congestion on each network segment. Filtering/Traffic Shaping Firewall firewall IP Masquerading The second common situation is where firewall functionality is needed without IP Masquerading (NAT). An example is a small company that is connected via DSL or ISDN to their ISP. They have a 13 globally-accessible IP addresses from their ISP and have 10 PCs on their network. In this situation, using a router-based firewall is difficult because of subnetting issues. router DSL ISDN A bridge-based firewall can be configured and dropped into the path just downstream of their DSL/ISDN router without any IP numbering issues. Configuring a Bridge Network Interface Card Selection A bridge requires at least two network cards to function. Unfortunately, not all network interface cards as of FreeBSD 4.0 support bridging. Read &man.bridge.4; for details on the cards that are supported. Install and test the two network cards before continuing. Kernel Configuration Changes kernel configuration kernel configuration options BRIDGE To enable kernel support for bridging, add the: options BRIDGE statement to your kernel configuration file, and rebuild your kernel. Firewall Support firewall If you are planning to use the bridge as a firewall, you will need to add the IPFIREWALL option as well. Read for general information on configuring the bridge as a firewall. If you need to allow non-IP packets (such as ARP) to flow through the bridge, there is an undocumented firewall option that must be set. This option is IPFIREWALL_DEFAULT_TO_ACCEPT. Note that this changes the default rule for the firewall to accept any packet. Make sure you know how this changes the meaning of your ruleset before you set it. Traffic Shaping Support If you want to use the bridge as a traffic shaper, you will need to add the DUMMYNET option to your kernel configuration. Read &man.dummynet.4; for further information. Enabling the Bridge Add the line: net.link.ether.bridge=1 to /etc/sysctl.conf to enable the bridge at runtime, and the line: net.link.ether.bridge_cfg=if1,if2 to enable bridging on the specified interfaces (replace if1 and if2 with the names of your two network interfaces). If you want the bridged packets to be filtered by &man.ipfw.8;, you should add: net.link.ether.bridge_ipfw=1 as well. Performance My bridge/firewall is a Pentium 90 with one 3Com 3C900B and one 3C905B. The protected side of the network runs at 10 mbps half duplex and the connection between the bridge and my router (a Cisco 675) runs at 100 mbps full duplex. With no filtering enabled, I have found that the bridge adds about 0.4 milliseconds of latency to pings from the protected 10 mbps network to the Cisco 675. Other Information If you want to be able to telnet into the bridge from the network, it is OK to assign one of the network cards an IP address. The consensus is that assigning both cards an address is a bad idea. If you have multiple bridges on your network, there cannot be more than one path between any two workstations. Technically, this means that there is no support for spanning tree link management. Tom Rhodes Reorganized and enhanced by Bill Swingle Written by NFS NFS Among the many different filesystems that FreeBSD supports is the Network File System, also known as NFS. NFS allows a system to share directories and files with others over a network. By using NFS, users and programs can access files on remote systems almost as if they were local files. Some of the most notable benefits that NFS can provide are: Local workstations use less disk space because commonly used data can be stored on a single machine and still remain accessible to others over the network. There is no need for users to have separate home directories on every network machine. Home directories could be setup on the NFS server and made available throughout the network. Storage devices such as floppy disks, CDROM drives, and ZIP drives can be used by other machines on the network. This may reduce the number of removable media drives throughout the network. How <acronym>NFS</acronym> Works NFS consists of at least two main parts: a server and one or more clients. The client remotely accesses the data that is stored on the server machine. In order for this to function properly a few processes have to be configured and running: The server has to be running the following daemons: NFS server portmap mountd nfsd Daemon Description nfsd The NFS daemon which services requests from the NFS clients. mountd The NFS mount daemon which carries out the requests that &man.nfsd.8; passes on to it. portmap The portmapper daemon allows NFS clients to discover which port the NFS server is using. The client can also run a daemon, known as nfsiod. The nfsiod daemon services the requests from the NFS server. This is optional, and improves performance, but is not required for normal and correct operation. See the &man.nfsiod.8; manual page for more information. Configuring <acronym>NFS</acronym> NFS configuration NFS configuration is a relatively straightforward process. The processes that need to be running can all start at boot time with a few modifications to your /etc/rc.conf file. On the NFS server, make sure that the following options are configured in the /etc/rc.conf file: portmap_enable="YES" nfs_server_enable="YES" mountd_flags="-r" mountd runs automatically whenever the NFS server is enabled. On the client, make sure this option is present in /etc/rc.conf: nfs_client_enable="YES" The /etc/exports file specifies which filesystems NFS should export (sometimes referred to as share). Each line in /etc/exports specifies a filesystem to be exported and which machines have access to that filesystem. Along with what machines have access to that filesystem, access options may also be specified. There are many such options that can be used in this file but only a few will be mentioned here. You can easily discover other options by reading over the &man.exports.5; manual page. Here are a few example /etc/exports entries: NFS Examples of exporting filesystems The following examples give an idea of how to export filesystems, although the settings may be different depending on your environment and network configuration. For instance, to export the /cdrom directory to three example machines that have the same domain name as the server (hence the lack of a domain name for each) or have entries in your /etc/hosts file. The flag makes the exported filesystem read-only. With this flag, the remote system will not be able to write any changes to the exported filesystem. /cdrom -ro host1 host2 host3 The following line exports /home to three hosts by IP address. This is a useful setup if you have a private network without a DNS server configured. Optionally the /etc/hosts file could be configured for internal hostnames; please review &man.hosts.5; for more information. The flag allows the subdirectories to be mount points. In other words, it will not mount the subdirectories but permit the client to mount only the directories that are required or needed. /home -alldirs 10.0.0.2 10.0.0.3 10.0.0.4 The following line exports /a so that two clients from different domains may access the filesystem. The flag allows the root user on the remote system to write data on the exported filesystem as root. If the -maproot=root flag is not specified, then even if a user has root access on the remote system, they will not be able to modify files on the exported filesystem. /a -maproot=root host.example.com box.example.org In order for a client to access an exported filesystem, the client must have permission to do so. Make sure the client is listed in your /etc/exports file. In /etc/exports, each line represents the export information for one filesystem to one host. A remote host can only be specified once per filesystem, and may only have one default entry. For example, assume that /usr is a single filesystem. The following /etc/exports would be invalid: /usr/src client /usr/ports client One filesystem, /usr, has two lines specifying exports to the same host, client. The correct format for this situation is: /usr/src /usr/ports client The properties of one filesystem exported to a given host must all occur on one line. Lines without a client specified are treated as a single host. This limits how you can export filesystems, but for most people this is not an issue. The following is an example of a valid export list, where /usr and /exports are local filesystems: # Export src and ports to client01 and client02, but only # client01 has root privileges on it /usr/src /usr/ports -maproot=root client01 /usr/src /usr/ports client02 # The client machines have root and can mount anywhere # on /exports. Anyone in the world can mount /exports/obj read-only /exports -alldirs -maproot=root client01 client02 /exports/obj -ro You must restart mountd whenever you modify /etc/exports so the changes can take effect. This can be accomplished by sending the HUP signal to the mountd process: &prompt.root; kill -HUP `cat /var/run/mountd.pid` Alternatively, a reboot will make FreeBSD set everything up properly. A reboot is not necessary though. Executing the following commands as root should start everything up. On the NFS server: &prompt.root; portmap &prompt.root; nfsd -u -t -n 4 &prompt.root; mountd -r On the NFS client: &prompt.root; nfsiod -n 4 Now everything should be ready to actually mount a remote file system. In these examples the server's name will be server and the client's name will be client. If you only want to temporarily mount a remote filesystem or would rather test the configuration, just execute a command like this as root on the client: NFS mounting filesystems &prompt.root; mount server:/home /mnt This will mount the /home directory on the server at /mnt on the client. If everything is set up correctly you should be able to enter /mnt on the client and see all the files that are on the server. If you want to automatically mount a remote filesystem each time the computer boots, add the filesystem to the /etc/fstab file. Here is an example: server:/home /mnt nfs rw 0 0 The &man.fstab.5; manual page lists all the available options. Practical Uses NFS has many practical uses. Some of the more common ones are listed below: NFS uses Set several machines to share a CDROM or other media among them. This is cheaper and often a more convenient method to install software on multiple machines. On large networks, it might be more convenient to configure a central NFS server in which to store all the user home directories. These home directories can then be exported to the network so that users would always have the same home directory, regardless of which workstation they log in to. Several machines could have a common /usr/ports/distfiles directory. That way, when you need to install a port on several machines, you can quickly access the source without downloading it on each machine. Wylie Stilwell Contributed by Chern Lee Rewritten by amd amd automatic mounter daemon &man.amd.8; (the automatic mounter daemon) automatically mounts a remote filesystem whenever a file or directory within that filesystem is accessed. Filesystems that are inactive for a period of time will also be automatically unmounted by amd. Using amd provides a simple alternative to permanent mounts, as permanent mounts are usually listed in /etc/fstab. amd operates by attaching itself as an NFS server to the /host and /net directories. When a file is accessed within one of these directories, amd looks up the corresponding remote mount and automatically mounts it. /net is used to mount an exported filesystem from an IP address, while /host is used to mount an export from a remote hostname. An access to a file within /host/foobar/usr would tell amd to attempt to mount the /usr export on the host foobar. Mounting an Export with <application>amd</application> You can view the available mounts of a remote host with the showmount command. For example, to view the mounts of a host named foobar, you can use: &prompt.user; showmount -e foobar Exports list on foobar: /usr 10.10.10.0 /a 10.10.10.0 &prompt.user; cd /host/foobar/usr As seen in the example, the showmount shows /usr as an export. When changing directories to /host/foobar/usr, amd attempts to resolve the hostname foobar and automatically mount the desired export. amd can be started by the startup scripts by placing the following lines in /etc/rc.conf: amd_enable="YES" Additionally, custom flags can be passed to amd from the amd_flags option. By default, amd_flags is set to: amd_flags="-a /.amd_mnt -l syslog /host /etc/amd.map /net /etc/amd.map" The /etc/amd.map file defines the default options that exports are mounted with. The /etc/amd.conf file defines some of the more advanced features of amd. Consult the &man.amd.8; and &man.amd.conf.5; manual pages for more information. John Lind Contributed by Problems Integrating with Other Systems Certain Ethernet adapters for ISA PC systems have limitations which can lead to serious network problems, particularly with NFS. This difficulty is not specific to FreeBSD, but FreeBSD systems are affected by it. The problem nearly always occurs when (FreeBSD) PC systems are networked with high-performance workstations, such as those made by Silicon Graphics, Inc., and Sun Microsystems, Inc. The NFS mount will work fine, and some operations may succeed, but suddenly the server will seem to become unresponsive to the client, even though requests to and from other systems continue to be processed. This happens to the client system, whether the client is the FreeBSD system or the workstation. On many systems, there is no way to shut down the client gracefully once this problem has manifested itself. The only solution is often to reset the client, because the NFS situation cannot be resolved. Though the correct solution is to get a higher performance and capacity Ethernet adapter for the FreeBSD system, there is a simple workaround that will allow satisfactory operation. If the FreeBSD system is the server, include the option on the mount from the client. If the FreeBSD system is the client, then mount the NFS filesystem with the option . These options may be specified using the fourth field of the fstab entry on the client for automatic mounts, or by using the parameter of the mount command for manual mounts. It should be noted that there is a different problem, sometimes mistaken for this one, when the NFS servers and clients are on different networks. If that is the case, make certain that your routers are routing the necessary UDP information, or you will not get anywhere, no matter what else you are doing. In the following examples, fastws is the host (interface) name of a high-performance workstation, and freebox is the host (interface) name of a FreeBSD system with a lower-performance Ethernet adapter. Also, /sharedfs will be the exported NFS filesystem (see &man.exports.5;), and /project will be the mount point on the client for the exported filesystem. In all cases, note that additional options, such as or and may be desirable in your application. Examples for the FreeBSD system (freebox) as the client in /etc/fstab on freebox: fastws:/sharedfs /project nfs rw,-r=1024 0 0 As a manual mount command on freebox: &prompt.root; mount -t nfs -o -r=1024 fastws:/sharedfs /project Examples for the FreeBSD system as the server in /etc/fstab on fastws: freebox:/sharedfs /project nfs rw,-w=1024 0 0 As a manual mount command on fastws: &prompt.root; mount -t nfs -o -w=1024 freebox:/sharedfs /project Nearly any 16-bit Ethernet adapter will allow operation without the above restrictions on the read or write size. For anyone who cares, here is what happens when the failure occurs, which also explains why it is unrecoverable. NFS typically works with a block size of 8 k (though it may do fragments of smaller sizes). Since the maximum Ethernet packet is around 1500 bytes, the NFS block gets split into multiple Ethernet packets, even though it is still a single unit to the upper-level code, and must be received, assembled, and acknowledged as a unit. The high-performance workstations can pump out the packets which comprise the NFS unit one right after the other, just as close together as the standard allows. On the smaller, lower capacity cards, the later packets overrun the earlier packets of the same unit before they can be transferred to the host and the unit as a whole cannot be reconstructed or acknowledged. As a result, the workstation will time out and try again, but it will try again with the entire 8 K unit, and the process will be repeated, ad infinitum. By keeping the unit size below the Ethernet packet size limitation, we ensure that any complete Ethernet packet received can be acknowledged individually, avoiding the deadlock situation. Overruns may still occur when a high-performance workstations is slamming data out to a PC system, but with the better cards, such overruns are not guaranteed on NFS units. When an overrun occurs, the units affected will be retransmitted, and there will be a fair chance that they will be received, assembled, and acknowledged. Jean-François Dockès Updated by Diskless Operation diskless workstation diskless operation A FreeBSD machine can boot over the network and operate without a local disk, using filesystems mounted from an NFS server. No system modification is necessary, beyond standard configuration files. Such a system is easy to set up because all the necessary elements are readily available: There are at least two possible methods to load the kernel over the network: PXE: Intel's Preboot Execution Environment system is a form of smart boot ROM built into some networking cards or motherboards. See &man.pxeboot.8; for more details. The etherboot port (net/etherboot) produces ROM-able code to boot kernels over the network. The code can be either burnt into a boot PROM on a network card, or loaded from a local floppy (or hard) disk drive, or from a running MS-DOS system. Many network cards are supported. A sample script (/usr/share/examples/diskless/clone_root) eases the creation and maintenance of the workstation's root filesystem on the server. The script will probably require a little customization but it will get you started very quickly. Standard system startup files exist in /etc to detect and support a diskless system startup. Swapping, if needed, can be done either to an NFS file or to a local disk. There are many ways to set up diskless workstations. Many elements are involved, and most can be customized to suit local taste. The following will describe the setup of a complete system, emphasizing simplicity and compatibility with the standard FreeBSD startup scripts. The system described has the following characteristics: The diskless workstations use a shared read-only root filesystem, and a shared read-only /usr. The root filesystem is a copy of a standard FreeBSD root (typically the server's), with some configuration files overridden by ones specific to diskless operation or, possibly, to the workstation they belong to. The parts of the root which have to be writable are overlaid with &man.mfs.8; filesystems. Any changes will be lost when the system reboots. The kernel is loaded by etherboot , using DHCP (or BOOTP) and TFTP. As described, this system is insecure. It should live in a protected area of a network, and be untrusted by other hosts. Setup Instructions Configuring DHCP/BOOTP There are two protocols that are commonly used to boot a workstation that retrieves its configuration over the network: BOOTP and DHCP. They are used at several points in the workstation bootstrap: etherboot uses DHCP (by default) or BOOTP (needs a configuration option) to find the kernel. (PXE uses DHCP). The kernel uses BOOTP to locate the NFS root. It is possible to configure a system to use only BOOTP. The &man.bootpd.8; server program is included in the base FreeBSD system. However, DHCP has a number of advantages over BOOTP (nicer configuration files, possibility of using PXE, plus many others not directly related to diskless operation), and we shall describe both a pure BOOTP, and a BOOTP+DHCP configuration, with an emphasis on the latter, which will use the ISC DHCP software package. Configuration Using ISC DHCP The isc-dhcp server can answer both BOOTP and DHCP requests. As of release 4.4, isc-dhcp 3.0 is not part of the base system. You will first need to install the net/isc-dhcp3 port or the corresponding package. Please refer to for general information about ports and packages. Once isc-dhcp is installed, it needs a configuration file to run, (normally named /usr/local/etc/dhcpd.conf). Here follows a commented example: default-lease-time 600; max-lease-time 7200; authoritative; option domain-name "example.com"; option domain-name-servers 192.168.4.1; option routers 192.168.4.1; subnet 192.168.4.0 netmask 255.255.255.0 { use-host-decl-names on; option subnet-mask 255.255.255.0; option broadcast-address 192.168.4.255; host margaux { hardware ethernet 01:23:45:67:89:ab; fixed-address margaux.example.com; next-server 192.168.4.4; filename "/tftpboot/kernel.diskless"; option root-path "192.168.4.4:/data/misc/diskless"; } } This option tells dhcpd to send the value in the host declarations as the hostname for the diskless host. An alternate way would be to add an option host-name margaux inside the host declarations. The next-server directive designates the TFTP server (the default is to use the same host as the DHCP server). The filename directive defines the file that etherboot will load as a kernel. PXE appears to prefer a relative file name, and it loads pxeboot, not the kernel (option filename "pxeboot"). The root-path option defines the path to the root filesystem, in usual NFS notation. Configuration Using BOOTP Here follows an equivalent bootpd configuration. This would be found in /etc/bootptab. Please note that etherboot must be compiled with the non-default option NO_DHCP_SUPPORT in order to use BOOTP, and that PXE needs DHCP. The only obvious advantage of bootpd is that it exists in the base system. .def100:\ :hn:ht=1:sa=192.168.4.4:vm=rfc1048:\ :sm=255.255.255.0:\ :ds=192.168.4.1:\ :gw=192.168.4.1:\ :hd="/tftpboot":\ :bf="/kernel.diskless":\ :rp="192.168.4.4:/data/misc/diskless": margaux:ha=0123456789ab:tc=.def100 Preparing a Boot Program with <application>Etherboot</application> Etherboot's Web site contains extensive documentation mainly intended for Linux systems, but nonetheless containing useful information. The following will just outline how you would use etherboot on a FreeBSD system. You must first install the net/etherboot package or port. The etherboot port can normally be found in /usr/ports/net/etherboot. If the ports tree is installed on your system, just typing make in this directory should take care of everything. Else refer to for information about ports and packages. For our setup, we shall use a boot floppy. For other methods (PROM, or dos program), please refer to the etherboot documentation. To make a boot floppy, insert a floppy in the drive on the machine where you installed etherboot, then change your current directory to the src directory in the etherboot tree and type: &prompt.root; gmake bin32/devicetype.fd0 devicetype depends on the type of the Ethernet card in the diskless workstation. Refer to the NIC file in the same directory to determine the right devicetype. Configuring the TFTP and NFS Servers You need to enable tftpd on the TFTP server: Create a directory from which tftpd will serve the files, i.e.: /tftpboot Add this line to your /etc/inetd.conf: tftp dgram udp wait nobody /usr/libexec/tftpd tftpd /tftpboot It appears that at least some PXE versions want the TCP version of TFTP. In this case, add a second line, replacing dgram udp with stream tcp. Tell inetd to reread its configuration file: &prompt.root; kill -HUP `cat /var/run/inetd.pid` You can place the tftpboot directory anywhere on the server. Make sure that the location is set in both inetd.conf and dhcpd.conf. You also need to enable NFS and export the appropriate filesystem on the NFS server. Add this to /etc/rc.conf: nfs_server_enable="YES" Export the filesystem where the diskless root directory is located by adding the following to /etc/exports (adjust the volume mount point and replace margaux with the name of the diskless workstation): /data/misc -alldirs -ro margaux Tell mountd to reread its configuration file. If you actually needed to enable NFS in /etc/rc.conf at the first step, you probably want to reboot instead. &prompt.root; kill -HUP `cat /var/run/mountd.pid` Building a Diskless Kernel Create a kernel configuration file for the diskless client with the following options (in addition to the usual ones): options BOOTP # Use BOOTP to obtain IP address/hostname options BOOTP_NFSROOT # NFS mount root filesystem using BOOTP info options BOOTP_COMPAT # Workaround for broken bootp daemons. You may also want to use BOOTP_NFSV3 and BOOTP_WIRED_TO (refer to LINT). Build the kernel (See ), and copy it to the tftp directory, under the name listed in dhcpd.conf. Preparing the root Filesystem You need to create a root filesystem for the diskless workstations, in the location listed as root-path in dhcpd.conf. The easiest way to do this is to use the /usr/share/examples/diskless/clone_root shell script. This script needs customization, at least to adjust the place where the filesystem will be created (the DEST variable). Refer to the comments at the top of the script for instructions. They explain how the base filesystem is built, and how files may be selectively overridden by versions specific to diskless operation, to a subnetwork, or to an individual workstation. They also give examples for the diskless /etc/fstab and /etc/rc.conf files. The README files in /usr/share/examples/diskless contain a lot of interesting background information, but, together with the other examples in the diskless directory, they actually document a configuration method which is distinct from the one used by clone_root and /etc/rc.diskless[12], which is a little confusing. Use them for reference only, except if you prefer the method that they describe, in which case you will need customized rc scripts. Configuring Swap If needed, a swap file located on the server can be accessed via NFS. The exact bootptab or dhcpd.conf options are not clearly documented at this time. The following configuration suggestions have been reported to work in some installations using isc-dhcp 3.0rc11. Add the following lines to dhcpd.conf: # Global section option swap-path code 128 = string; option swap-size code 129 = integer 32; host margaux { ... # Standard lines, see above option swap-path "192.168.4.4:/netswapvolume/netswap"; option swap-size 64000; } The idea is that, at least for a FreeBSD client, DHCP/BOOTP option code 128 is the path to the NFS swap file, and option code 129 is the swap size in kilobytes. Older versions of dhcpd allowed a syntax of option option-128 "..., which does not seem to work any more. /etc/bootptab would use the following syntax instead: T128="192.168.4.4:/netswapvolume/netswap":T129=64000 On the NFS swap file server, create the swap file(s) &prompt.root; mkdir /netswapvolume/netswap &prompt.root; cd /netswapvolume/netswap &prompt.root; dd if=/dev/zero bs=1024 count=64000 of=swap.192.168.4.6 &prompt.root; chmod 0600 swap.192.168.4.6 192.168.4.6 is the IP address for the diskless client. On the NFS swap file server, add the following line to /etc/exports: /netswapvolume -maproot=0:10 -alldirs margaux Then tell mountd to reread the exports file, as above. Miscellaneous Issues Running with a read-only <filename>/usr</filename>If the diskless workstation is configured to run X, you will have to adjust the xdm configuration file, which puts the error log on /usr by default. Using a non-FreeBSD Server When the server for the root filesystem is not running FreeBSD, you will have to create the root filesystem on a FreeBSD machine, then copy it to its destination, using tar or cpio. In this situation, there are sometimes problems with the special files in /dev, due to differing major/minor integer sizes. A solution to this problem is to export a directory from the non-FreeBSD server, mount this directory onto a FreeBSD machine, and run MAKEDEV on the FreeBSD machine to create the correct device entries (FreeBSD 5.0 and later use &man.devfs.5; to allocate device nodes transparently for the user, running MAKEDEV on these versions is useless). ISDN A good resource for information on ISDN technology and hardware is Dan Kegel's ISDN Page. A quick simple road map to ISDN follows: If you live in Europe you might want to investigate the ISDN card section. If you are planning to use ISDN primarily to connect to the Internet with an Internet Provider on a dial-up non-dedicated basis, you might look into Terminal Adapters. This will give you the most flexibility, with the fewest problems, if you change providers. If you are connecting two LANs together, or connecting to the Internet with a dedicated ISDN connection, you might consider the stand alone router/bridge option. Cost is a significant factor in determining what solution you will choose. The following options are listed from least expensive to most expensive. Hellmuth Michaelis Contributed by ISDN Cards ISDN cards FreeBSD's ISDN implementation supports only the DSS1/Q.931 (or Euro-ISDN) standard using passive cards. Starting with FreeBSD 4.4, some active cards are supported where the firmware also supports other signaling protocols; this also includes the first supported Primary Rate (PRI) ISDN card. Isdn4bsd allows you to connect to other ISDN routers using either IP over raw HDLC or by using synchronous PPP: either by using kernel PPP with isppp, a modified sppp driver, or by using userland &man.ppp.8;. By using userland &man.ppp.8;, channel bonding of two or more ISDN B-channels is possible. A telephone answering machine application is also available as well as many utilities such as a software 300 Baud modem. Some growing number of PC ISDN cards are supported under FreeBSD and the reports show that it is successfully used all over Europe and in many other parts of the world. The passive ISDN cards supported are mostly the ones with the Infineon (formerly Siemens) ISAC/HSCX/IPAC ISDN chipsets, but also ISDN cards with chips from Cologne Chip (ISA bus only), PCI cards with Winbond W6692 chips, some cards with the Tiger300/320/ISAC chipset combinations and some vendor specific chipset based cards such as the AVM Fritz!Card PCI V.1.0 and the AVM Fritz!Card PnP. Currently the active supported ISDN cards are the AVM B1 (ISA and PCI) BRI cards and the AVM T1 PCI PRI cards. For documentation on isdn4bsd, have a look at /usr/share/examples/isdn/ directory on your FreeBSD system or at the homepage of isdn4bsd which also has pointers to hints, erratas and much more documentation such as the isdn4bsd handbook. In case you are interested in adding support for a different ISDN protocol, a currently unsupported ISDN PC card or otherwise enhancing isdn4bsd, please get in touch with &a.hm;. For questions regarding the installation, configuration and troubleshooting isdn4bsd, a majordomo maintained mailing list is available. To join, send mail to &a.majordomo; and specify: subscribe freebsd-isdn in the body of your message. ISDN Terminal Adapters Terminal adapters(TA), are to ISDN what modems are to regular phone lines. modem Most TA's use the standard hayes modem AT command set, and can be used as a drop in replacement for a modem. A TA will operate basically the same as a modem except connection and throughput speeds will be much faster than your old modem. You will need to configure PPP exactly the same as for a modem setup. Make sure you set your serial speed as high as possible. PPP The main advantage of using a TA to connect to an Internet Provider is that you can do Dynamic PPP. As IP address space becomes more and more scarce, most providers are not willing to provide you with a static IP anymore. Most stand-alone routers are not able to accommodate dynamic IP allocation. TA's completely rely on the PPP daemon that you are running for their features and stability of connection. This allows you to upgrade easily from using a modem to ISDN on a FreeBSD machine, if you already have PPP setup. However, at the same time any problems you experienced with the PPP program and are going to persist. If you want maximum stability, use the kernel PPP option, not the user-land iijPPP. The following TA's are known to work with FreeBSD. Motorola BitSurfer and Bitsurfer Pro Adtran Most other TA's will probably work as well, TA vendors try to make sure their product can accept most of the standard modem AT command set. The real problem with external TA's is that, like modems, you need a good serial card in your computer. You should read the FreeBSD Serial Hardware tutorial for a detailed understanding of serial devices, and the differences between asynchronous and synchronous serial ports. A TA running off a standard PC serial port (asynchronous) limits you to 115.2 Kbs, even though you have a 128 Kbs connection. To fully utilize the 128 Kbs that ISDN is capable of, you must move the TA to a synchronous serial card. Do not be fooled into buying an internal TA and thinking you have avoided the synchronous/asynchronous issue. Internal TA's simply have a standard PC serial port chip built into them. All this will do is save you having to buy another serial cable and find another empty electrical socket. A synchronous card with a TA is at least as fast as a stand-alone router, and with a simple 386 FreeBSD box driving it, probably more flexible. The choice of sync/TA v.s. stand-alone router is largely a religious issue. There has been some discussion of this in the mailing lists. I suggest you search the archives for the complete discussion. Stand-alone ISDN Bridges/Routers ISDN stand-alone bridges/routers ISDN bridges or routers are not at all specific to FreeBSD or any other operating system. For a more complete description of routing and bridging technology, please refer to a Networking reference book. In the context of this page, the terms router and bridge will be used interchangeably. As the cost of low end ISDN routers/bridges comes down, it will likely become a more and more popular choice. An ISDN router is a small box that plugs directly into your local Ethernet network, and manages its own connection to the other bridge/router. It has built in software to communicate via PPP and other popular protocols. A router will allow you much faster throughput than a standard TA, since it will be using a full synchronous ISDN connection. The main problem with ISDN routers and bridges is that interoperability between manufacturers can still be a problem. If you are planning to connect to an Internet provider, you should discuss your needs with them. If you are planning to connect two LAN segments together, such as your home LAN to the office LAN, this is the simplest lowest maintenance solution. Since you are buying the equipment for both sides of the connection you can be assured that the link will work. For example to connect a home computer or branch office network to a head office network the following setup could be used. Branch Office or Home Network 10 base 2 Network uses a bus based topology with 10 base 2 Ethernet (thinnet). Connect router to network cable with AUI/10BT transceiver, if necessary. ---Sun workstation | ---FreeBSD box | ---Windows 95 (Do not admit to owning it) | Stand-alone router | ISDN BRI line 10 Base 2 Ethernet If your home/branch office is only one computer you can use a twisted pair crossover cable to connect to the stand-alone router directly. Head Office or Other LAN 10 base T Network uses a star topology with 10 base T Ethernet (Twisted Pair). -------Novell Server | H | | ---Sun | | | U ---FreeBSD | | | ---Windows 95 | B | |___---Stand-alone router | ISDN BRI line ISDN Network Diagram One large advantage of most routers/bridges is that they allow you to have 2 separate independent PPP connections to 2 separate sites at the same time. This is not supported on most TA's, except for specific (usually expensive) models that have two serial ports. Do not confuse this with channel bonding, MPP, etc. This can be a very useful feature if, for example, you have an dedicated ISDN connection at your office and would like to tap into it, but do not want to get another ISDN line at work. A router at the office location can manage a dedicated B channel connection (64 Kbps) to the Internet and use the other B channel for a separate data connection. The second B channel can be used for dial-in, dial-out or dynamically bonding (MPP, etc.) with the first B channel for more bandwidth. IPX/SPX An Ethernet bridge will also allow you to transmit more than just IP traffic. You can also send IPX/SPX or whatever other protocols you use. Bill Swingle Written by Eric Ogren Enhanced by Udo Erdelhoff NIS/YP What Is It? NIS Solaris HP-UX AIX Linux NetBSD OpenBSD NIS, which stands for Network Information Services, was developed by Sun Microsystems to centralize administration of Unix (originally SunOS) systems. It has now essentially become an industry standard; all major Unix systems (Solaris, HP-UX, AIX, Linux, NetBSD, OpenBSD, FreeBSD, etc) support NIS. yellow pagesNIS NIS was formerly known as Yellow Pages, but because of trademark issues, Sun changed the name. The old term (and yp) is still often seen and used. NIS domains It is a RPC-based client/server system that allows a group of machines within an NIS domain to share a common set of configuration files. This permits a system administrator to set up NIS client systems with only minimal configuration data and add, remove or modify configuration data from a single location. Windows NT It is similar to Windows NT's domain system; although the internal implementation of the two are not at all similar, the basic functionality can be compared. Terms/Processes You Should Know There are several terms and several important user processes that you will come across when attempting to implement NIS on FreeBSD, whether you are trying to create an NIS server or act as an NIS client: portmap Term Description NIS domainname An NIS master server and all of its clients (including its slave servers) have a NIS domainname. Similar to an NT domain name, the NIS domainname does not have anything to do with DNS. portmap Must be running in order to enable RPC (Remote Procedure Call, a network protocol used by NIS). If portmap is not running, it will be impossible to run an NIS server, or to act as an NIS client. ypbind binds an NIS client to its NIS server. It will take the NIS domainname from the system, and using RPC, connect to the server. ypbind is the core of client-server communication in an NIS environment; if ypbind dies on a client machine, it will not be able to access the NIS server. ypserv Should only be running on NIS servers, is the NIS server process itself. If &man.ypserv.8; dies, then the server will no longer be able to respond to NIS requests (hopefully, there is a slave server to take over for it). There are some implementations of NIS (but not the FreeBSD one), that do not try to reconnect to another server if the server it used before dies. Often, the only thing that helps in this case is to restart the server process (or even the whole server) or the ypbind process on the client. rpc.yppasswdd Another process that should only be running on NIS master servers, is a daemon that will allow NIS clients to change their NIS passwords. If this daemon is not running, users will have to login to the NIS master server and change their passwords there. How Does It Work? There are three types of hosts in an NIS environment: master servers, slave servers, and clients. Servers act as a central repository for host configuration information. Master servers hold the authoritative copy of this information, while slave servers mirror this information for redundancy. Clients rely on the servers to provide this information to them. Information in many files can be shared in this manner. The master.passwd, group, and hosts files are commonly shared via NIS. Whenever a process on a client needs information that would normally be found in these files locally, it makes a query to the NIS server that it is bound to instead. Machine Types NIS master server A NIS master server. This server, analogous to a Windows NT primary domain controller, maintains the files used by all of the NIS clients. The passwd, group, and other various files used by the NIS clients live on the master server. It is possible for one machine to be an NIS master server for more than one NIS domain. However, this will not be covered in this introduction, which assumes a relatively small-scale NIS environment. NIS slave server NIS slave servers. Similar to NT's backup domain controllers, NIS slave servers maintain copies of the NIS master's data files. NIS slave servers provide the redundancy, which is needed in important environments. They also help to balance the load of the master server: NIS Clients always attach to the NIS server whose response they get first, and this includes slave-server-replies. NIS client NIS clients. NIS clients, like most NT workstations, authenticate against the NIS server (or the NT domain controller in the NT Workstation case) to log on. Using NIS/YP This section will deal with setting up a sample NIS environment. This section assumes that you are running FreeBSD 3.3 or later. The instructions given here will probably work for any version of FreeBSD greater than 3.0, but there are no guarantees that this is true. Planning Let us assume that you are the administrator of a small university lab. This lab, which consists of 15 FreeBSD machines, currently has no centralized point of administration; each machine has its own /etc/passwd and /etc/master.passwd. These files are kept in sync with each other only through manual intervention; currently, when you add a user to the lab, you must run adduser on all 15 machines. Clearly, this has to change, so you have decided to convert the lab to use NIS, using two of the machines as servers. Therefore, the configuration of the lab now looks something like: Machine name IP address Machine role ellington 10.0.0.2 NIS master coltrane 10.0.0.3 NIS slave basie 10.0.0.4 Faculty workstation bird 10.0.0.5 Client machine cli[1-11] 10.0.0.[6-17] Other client machines If you are setting up a NIS scheme for the first time, it is a good idea to think through how you want to go about it. No matter what the size of your network, there are a few decisions that need to be made. Choosing a NIS Domain Name NIS domainname This might not be the domainname that you are used to. It is more accurately called the NIS domainname. When a client broadcasts its requests for info, it includes the name of the NIS domain that it is part of. This is how multiple servers on one network can tell which server should answer which request. Think of the NIS domainname as the name for a group of hosts that are related in some way. Some organizations choose to use their Internet domainname for their NIS domainname. This is not recommended as it can cause confusion when trying to debug network problems. The NIS domainname should be unique within your network and it is helpful if it describes the group of machines it represents. For example, the Art department at Acme Inc. might be in the acme-art NIS domain. For this example, assume you have chosen the name test-domain. SunOS However, some operating systems (notably SunOS) use their NIS domain name as their Internet domain name. If one or more machines on your network have this restriction, you must use the Internet domain name as your NIS domain name. Physical Server Requirements There are several things to keep in mind when choosing a machine to use as a NIS server. One of the unfortunate things about NIS is the level of dependency the clients have on the server. If a client cannot contact the server for its NIS domain, very often the machine becomes unusable. The lack of user and group information causes most systems to temporarily freeze up. With this in mind you should make sure to choose a machine that will not be prone to being rebooted regularly, or one that might be used for development. The NIS server should ideally be a stand alone machine whose sole purpose in life is to be an NIS server. If you have a network that is not very heavily used, it is acceptable to put the NIS server on a machine running other services, just keep in mind that if the NIS server becomes unavailable, it will affect all of your NIS clients adversely. NIS Servers The canonical copies of all NIS information are stored on a single machine called the NIS master server. The databases used to store the information are called NIS maps. In FreeBSD, these maps are stored in /var/yp/[domainname] where [domainname] is the name of the NIS domain being served. A single NIS server can support several domains at once, therefore it is possible to have several such directories, one for each supported domain. Each domain will have its own independent set of maps. NIS master and slave servers handle all NIS requests with the ypserv daemon. ypserv is responsible for receiving incoming requests from NIS clients, translating the requested domain and map name to a path to the corresponding database file and transmitting data from the database back to the client. Setting Up a NIS Master Server NIS server configuration Setting up a master NIS server can be relatively straight forward, depending on your needs. FreeBSD comes with support for NIS out-of-the-box. All you need is to add the following lines to /etc/rc.conf, and FreeBSD will do the rest for you. nisdomainname="test-domain" This line will set the NIS domainname to test-domain upon network setup (e.g. after reboot). nis_server_enable="YES" This will tell FreeBSD to start up the NIS server processes when the networking is next brought up. nis_yppasswdd_enable="YES" This will enable the rpc.yppasswdd daemon which, as mentioned above, will allow users to change their NIS password from a client machine. Depending on your NIS setup, you may need to add further entries. See the section about NIS servers that are also NIS clients, below, for details. Now, all you have to do is to run the command /etc/netstart as superuser. It will set up everything for you, using the values you defined in /etc/rc.conf. Initializing the NIS Maps NIS maps The NIS maps are database files, that are kept in the /var/yp directory. They are generated from configuration files in the /etc directory of the NIS master, with one exception: the /etc/master.passwd file. This is for a good reason; you do not want to propagate passwords to your root and other administrative accounts to all the servers in the NIS domain. Therefore, before we initialize the NIS maps, you should: &prompt.root; cp /etc/master.passwd /var/yp/master.passwd &prompt.root; cd /var/yp &prompt.root; vi master.passwd You should remove all entries regarding system accounts (bin, tty, kmem, games, etc), as well as any accounts that you do not want to be propagated to the NIS clients (for example root and any other UID 0 (superuser) accounts). Make sure the /var/yp/master.passwd is neither group nor world readable (mode 600)! Use the chmod command, if appropriate. Tru64 Unix When you have finished, it is time to initialize the NIS maps! FreeBSD includes a script named ypinit to do this for you (see its manual page for more information). Note that this script is available on most Unix Operating Systems, but not on all. On Digital Unix/Compaq Tru64 Unix it is called ypsetup. Because we are generating maps for an NIS master, we are going to pass the option to ypinit. To generate the NIS maps, assuming you already performed the steps above, run: ellington&prompt.root; ypinit -m test-domain Server Type: MASTER Domain: test-domain Creating an YP server will require that you answer a few questions. Questions will all be asked at the beginning of the procedure. Do you want this procedure to quit on non-fatal errors? [y/n: n] n Ok, please remember to go back and redo manually whatever fails. If you don't, something might not work. At this point, we have to construct a list of this domains YP servers. rod.darktech.org is already known as master server. Please continue to add any slave servers, one per line. When you are done with the list, type a <control D>. master server : ellington next host to add: coltrane next host to add: ^D The current list of NIS servers looks like this: ellington coltrane Is this correct? [y/n: y] y [..output from map generation..] NIS Map update completed. ellington has been setup as an YP master server without any errors. ypinit should have created /var/yp/Makefile from /var/yp/Makefile.dist. When created, this file assumes that you are operating in a single server NIS environment with only FreeBSD machines. Since test-domain has a slave server as well, you must edit /var/yp/Makefile: ellington&prompt.root; vi /var/yp/Makefile You should comment out the line that says NOPUSH = "True" (if it is not commented out already). Setting up a NIS Slave Server NIS configuring a slave server Setting up an NIS slave server is even more simple than setting up the master. Log on to the slave server and edit the file /etc/rc.conf as you did before. The only difference is that we now must use the option when running ypinit. The option requires the name of the NIS master be passed to it as well, so our command line looks like: coltrane&prompt.root; ypinit -s ellington test-domain Server Type: SLAVE Domain: test-domain Master: ellington Creating an YP server will require that you answer a few questions. Questions will all be asked at the beginning of the procedure. Do you want this procedure to quit on non-fatal errors? [y/n: n] n Ok, please remember to go back and redo manually whatever fails. If you don't, something might not work. There will be no further questions. The remainder of the procedure should take a few minutes, to copy the databases from ellington. Transferring netgroup... ypxfr: Exiting: Map successfully transferred Transferring netgroup.byuser... ypxfr: Exiting: Map successfully transferred Transferring netgroup.byhost... ypxfr: Exiting: Map successfully transferred Transferring master.passwd.byuid... ypxfr: Exiting: Map successfully transferred Transferring passwd.byuid... ypxfr: Exiting: Map successfully transferred Transferring passwd.byname... ypxfr: Exiting: Map successfully transferred Transferring group.bygid... ypxfr: Exiting: Map successfully transferred Transferring group.byname... ypxfr: Exiting: Map successfully transferred Transferring services.byname... ypxfr: Exiting: Map successfully transferred Transferring rpc.bynumber... ypxfr: Exiting: Map successfully transferred Transferring rpc.byname... ypxfr: Exiting: Map successfully transferred Transferring protocols.byname... ypxfr: Exiting: Map successfully transferred Transferring master.passwd.byname... ypxfr: Exiting: Map successfully transferred Transferring networks.byname... ypxfr: Exiting: Map successfully transferred Transferring networks.byaddr... ypxfr: Exiting: Map successfully transferred Transferring netid.byname... ypxfr: Exiting: Map successfully transferred Transferring hosts.byaddr... ypxfr: Exiting: Map successfully transferred Transferring protocols.bynumber... ypxfr: Exiting: Map successfully transferred Transferring ypservers... ypxfr: Exiting: Map successfully transferred Transferring hosts.byname... ypxfr: Exiting: Map successfully transferred coltrane has been setup as an YP slave server without any errors. Don't forget to update map ypservers on ellington. You should now have a directory called /var/yp/test-domain. Copies of the NIS master server's maps should be in this directory. You will need to make sure that these stay updated. The following /etc/crontab entries on your slave servers should do the job: 20 * * * * root /usr/libexec/ypxfr passwd.byname 21 * * * * root /usr/libexec/ypxfr passwd.byuid These two lines force the slave to sync its maps with the maps on the master server. Although these entries are not mandatory, since the master server attempts to ensure any changes to its NIS maps are communicated to its slaves and because password information is vital to systems depending on the server, it is a good idea to force the updates. This is more important on busy networks where map updates might not always complete. Now, run the command /etc/netstart on the slave server as well, which again starts the NIS server. NIS Clients An NIS client establishes what is called a binding to a particular NIS server using the ypbind daemon. ypbind checks the system's default domain (as set by the domainname command), and begins broadcasting RPC requests on the local network. These requests specify the name of the domain for which ypbind is attempting to establish a binding. If a server that has been configured to serve the requested domain receives one of the broadcasts, it will respond to ypbind, which will record the server's address. If there are several servers available (a master and several slaves, for example), ypbind will use the address of the first one to respond. From that point on, the client system will direct all of its NIS requests to that server. ypbind will occasionally ping the server to make sure it is still up and running. If it fails to receive a reply to one of its pings within a reasonable amount of time, ypbind will mark the domain as unbound and begin broadcasting again in the hopes of locating another server. Setting Up an NIS Client NIS client configuration Setting up a FreeBSD machine to be a NIS client is fairly straightforward. Edit the file /etc/rc.conf and add the following lines in order to set the NIS domainname and start ypbind upon network startup: nisdomainname="test-domain" nis_client_enable="YES" To import all possible password entries from the NIS server, remove all user accounts from your /etc/master.passwd file and use vipw to add the following line to the end of the file: +::::::::: This line will afford anyone with a valid account in the NIS server's password maps an account. There are many ways to configure your NIS client by changing this line. See the netgroups section below for more information. For more detailed reading see O'Reilly's book on Managing NFS and NIS. You should keep at least one local account (i.e. not imported via NIS) in your /etc/master.passwd and this account should also be a member of the group wheel. If there is something wrong with NIS, this account can be used to log in remotely, become root, and fix things. To import all possible group entries from the NIS server, add this line to your /etc/group file: +:*:: After completing these steps, you should be able to run ypcat passwd and see the NIS server's passwd map. NIS Security In general, any remote user can issue an RPC to &man.ypserv.8; and retrieve the contents of your NIS maps, provided the remote user knows your domainname. To prevent such unauthorized transactions, &man.ypserv.8; supports a feature called securenets which can be used to restrict access to a given set of hosts. At startup, &man.ypserv.8; will attempt to load the securenets information from a file called /var/yp/securenets. This path varies depending on the path specified with the option. This file contains entries that consist of a network specification and a network mask separated by white space. Lines starting with # are considered to be comments. A sample securenets file might look like this: # allow connections from local host -- mandatory 127.0.0.1 255.255.255.255 # allow connections from any host # on the 192.168.128.0 network 192.168.128.0 255.255.255.0 # allow connections from any host # between 10.0.0.0 to 10.0.15.255 # this includes the machines in the testlab 10.0.0.0 255.255.240.0 If &man.ypserv.8; receives a request from an address that matches one of these rules, it will process the request normally. If the address fails to match a rule, the request will be ignored and a warning message will be logged. If the /var/yp/securenets file does not exist, ypserv will allow connections from any host. The ypserv program also has support for Wietse Venema's tcpwrapper package. This allows the administrator to use the tcpwrapper configuration files for access control instead of /var/yp/securenets. While both of these access control mechanisms provide some security, they, like the privileged port test, are vulnerable to IP spoofing attacks. All NIS-related traffic should be blocked at your firewall. Servers using /var/yp/securenets may fail to serve legitimate NIS clients with archaic TCP/IP implementations. Some of these implementations set all host bits to zero when doing broadcasts and/or fail to observe the subnet mask when calculating the broadcast address. While some of these problems can be fixed by changing the client configuration, other problems may force the retirement of the client systems in question or the abandonment of /var/yp/securenets. Using /var/yp/securenets on a server with such an archaic implementation of TCP/IP is a really bad idea and will lead to loss of NIS functionality for large parts of your network. tcpwrapper The use of the tcpwrapper package increases the latency of your NIS server. The additional delay may be long enough to cause timeouts in client programs, especially in busy networks or with slow NIS servers. If one or more of your client systems suffers from these symptoms, you should convert the client systems in question into NIS slave servers and force them to bind to themselves. Barring Some Users from Logging On In our lab, there is a machine basie that is supposed to be a faculty only workstation. We do not want to take this machine out of the NIS domain, yet the passwd file on the master NIS server contains accounts for both faculty and students. What can we do? There is a way to bar specific users from logging on to a machine, even if they are present in the NIS database. To do this, all you must do is add -username to the end of the /etc/master.passwd file on the client machine, where username is the username of the user you wish to bar from logging in. This should preferably be done using vipw, since vipw will sanity check your changes to /etc/master.passwd, as well as automatically rebuild the password database when you finish editing. For example, if we wanted to bar user bill from logging on to basie we would: basie&prompt.root; vipw [add -bill to the end, exit] vipw: rebuilding the database... vipw: done basie&prompt.root; cat /etc/master.passwd root:[password]:0:0::0:0:The super-user:/root:/bin/csh toor:[password]:0:0::0:0:The other super-user:/root:/bin/sh daemon:*:1:1::0:0:Owner of many system processes:/root:/sbin/nologin operator:*:2:5::0:0:System &:/:/sbin/nologin bin:*:3:7::0:0:Binaries Commands and Source,,,:/:/sbin/nologin tty:*:4:65533::0:0:Tty Sandbox:/:/sbin/nologin kmem:*:5:65533::0:0:KMem Sandbox:/:/sbin/nologin games:*:7:13::0:0:Games pseudo-user:/usr/games:/sbin/nologin news:*:8:8::0:0:News Subsystem:/:/sbin/nologin man:*:9:9::0:0:Mister Man Pages:/usr/share/man:/sbin/nologin bind:*:53:53::0:0:Bind Sandbox:/:/sbin/nologin uucp:*:66:66::0:0:UUCP pseudo-user:/var/spool/uucppublic:/usr/libexec/uucp/uucico xten:*:67:67::0:0:X-10 daemon:/usr/local/xten:/sbin/nologin pop:*:68:6::0:0:Post Office Owner:/nonexistent:/sbin/nologin nobody:*:65534:65534::0:0:Unprivileged user:/nonexistent:/sbin/nologin +::::::::: -bill basie&prompt.root; Udo Erdelhoff Contributed by Using Netgroups netgroups The method shown in the previous section works reasonably well if you need special rules for a very small number of users and/or machines. On larger networks, you will forget to bar some users from logging onto sensitive machines, or you may even have to modify each machine separately, thus losing the main benefit of NIS, centralized administration. The NIS developers' solution for this problem is called netgroups. Their purpose and semantics can be compared to the normal groups used by Unix file systems. The main differences are the lack of a numeric id and the ability to define a netgroup by including both user accounts and other netgroups. Netgroups were developed to handle large, complex networks with hundreds of users and machines. On one hand, this is a Good Thing if you are forced to deal with such a situation. On the other hand, this complexity makes it almost impossible to explain netgroups with really simple examples. The example used in the remainder of this section demonstrates this problem. Let us assume that your successful introduction of NIS in your laboratory caught your superiors' interest. Your next job is to extend your NIS domain to cover some of the other machines on campus. The two tables contain the names of the new users and new machines as well as brief descriptions of them. User Name(s) Description alpha, beta Normal employees of the IT department charlie, delta The new apprentices of the IT department echo, foxtrott, golf, ... Ordinary employees able, baker, ... The current interns Machine Name(s) Description war, death, famine, pollution Your most important servers. Only the IT employees are allowed to log onto these machines. pride, greed, envy, wrath, lust, sloth Less important servers. All members of the IT department are allowed to login onto these machines. one, two, three, four, ... Ordinary workstations. Only the real employees are allowed to use these machines. trashcan A very old machine without any critical data. Even the intern is allowed to use this box. If you tried to implement these restrictions by separately blocking each user, you would have to add one -user line to each system's passwd for each user who is not allowed to login onto that system. If you forget just one entry, you could be in trouble. It may be feasible to do this correctly during the initial setup, however you will eventually forget to add the lines for new users during day-to-day operations. After all, Murphy was an optimist. Handling this situation with netgroups offers several advantages. Each user need not be handled separately; you assign a user to one or more netgroups and allow or forbid logins for all members of the netgroup. If you add a new machine, you will only have to define login restrictions for netgroups. If a new user is added, you will only have to add the user to one or more netgroups. Those changes are independent of each other; no more for each combination of user and machine do... If your NIS setup is planned carefully, you will only have to modify exactly one central configuration file to grant or deny access to machines. The first step is the initialization of the NIS map netgroup. FreeBSD's &man.ypinit.8; does not create this map by default, but its NIS implementation will support it once it has been created. To create an empty map, simply type ellington&prompt.root; vi /var/yp/netgroup and start adding content. For our example, we need at least four netgroups: IT employees, IT apprentices, normal employees and interns. IT_EMP (,alpha,test-domain) (,beta,test-domain) IT_APP (,charlie,test-domain) (,delta,test-domain) USERS (,echo,test-domain) (,foxtrott,test-domain) \ (,golf,test-domain) INTERNS (,able,test-domain) (,baker,test-domain) IT_EMP, IT_APP etc. are the names of the netgroups. Each bracketed group adds one or more user accounts to it. The three fields inside a group are: The name of the host(s) where the following items are valid. If you do not specify a hostname, the entry is valid on all hosts. If you do specify a hostname, you will enter a realm of darkness, horror and utter confusion. The name of the account that belongs to this netgroup. The NIS domain for the account. You can import accounts from other NIS domains into your netgroup if you are one of the unlucky fellows with more than one NIS domain. Each of these fields can contain wildcards. See &man.netgroup.5; for details. netgroups Netgroup names longer than 8 characters should not be used, especially if you have machines running other operating systems within your NIS domain. The names are case sensitive; using capital letters for your netgroup names is an easy way to distinguish between user, machine and netgroup names. Some NIS clients (other than FreeBSD) cannot handle netgroups with a large number of entries. For example, some older versions of SunOS start to cause trouble if a netgroup contains more than 15 entries. You can circumvent this limit by creating several sub-netgroups with 15 users or less and a real netgroup that consists of the sub-netgroups: BIGGRP1 (,joe1,domain) (,joe2,domain) (,joe3,domain) [...] BIGGRP2 (,joe16,domain) (,joe17,domain) [...] BIGGRP3 (,joe31,domain) (,joe32,domain) BIGGROUP BIGGRP1 BIGGRP2 BIGGRP3 You can repeat this process if you need more than 225 users within a single netgroup. Activating and distributing your new NIS map is easy: ellington&prompt.root; cd /var/yp ellington&prompt.root; make This will generate the three NIS maps netgroup, netgroup.byhost and netgroup.byuser. Use &man.ypcat.1; to check if your new NIS maps are available: ellington&prompt.user; ypcat -k netgroup ellington&prompt.user; ypcat -k netgroup.byhost ellington&prompt.user; ypcat -k netgroup.byuser The output of the first command should resemble the contents of /var/yp/netgroup. The second command will not produce output if you have not specified host-specific netgroups. The third command can be used to get the list of netgroups for a user. The client setup is quite simple. To configure the server war, you only have to start &man.vipw.8; and replace the line +::::::::: with +@IT_EMP::::::::: Now, only the data for the users defined in the netgroup IT_EMP is imported into war's password database and only these users are allowed to login. Unfortunately, this limitation also applies to the ~ function of the shell and all routines converting between user names and numerical user ids. In other words, cd ~user will not work, ls -l will show the numerical id instead of the username and find . -user joe -print will fail with No such user. To fix this, you will have to import all user entries without allowing them to login onto your servers. This can be achieved by adding another line to /etc/master.passwd. This line should contain: +:::::::::/sbin/nologin, meaning Import all entries but replace the shell with /sbin/nologin in the imported entries. You can replace any field in the passwd entry by placing a default value in your /etc/master.passwd. Make sure that the line +:::::::::/sbin/nologin is placed after +@IT_EMP:::::::::. Otherwise, all user accounts imported from NIS will have /sbin/nologin as their login shell. After this change, you will only have to change one NIS map if a new employee joins the IT department. You could use a similar approach for the less important servers by replacing the old +::::::::: in their local version of /etc/master.passwd with something like this: +@IT_EMP::::::::: +@IT_APP::::::::: +:::::::::/sbin/nologin The corresponding lines for the normal workstations could be: +@IT_EMP::::::::: +@USERS::::::::: +:::::::::/sbin/nologin And everything would be fine until there is a policy change a few weeks later: The IT department starts hiring interns. The IT interns are allowed to use the normal workstations and the less important servers; and the IT apprentices are allowed to login onto the main servers. You add a new netgroup IT_INTERN, add the new IT interns to this netgroup and start to change the config on each and every machine... As the old saying goes: Errors in centralized planning lead to global mess. NIS' ability to create netgroups from other netgroups can be used to prevent situations like these. One possibility is the creation of role-based netgroups. For example, you could create a netgroup called BIGSRV to define the login restrictions for the important servers, another netgroup called SMALLSRV for the less important servers and a third netgroup called USERBOX for the normal workstations. Each of these netgroups contains the netgroups that are allowed to login onto these machines. The new entries for your NIS map netgroup should look like this: BIGSRV IT_EMP IT_APP SMALLSRV IT_EMP IT_APP ITINTERN USERBOX IT_EMP ITINTERN USERS This method of defining login restrictions works reasonably well if you can define groups of machines with identical restrictions. Unfortunately, this is the exception and not the rule. Most of the time, you will need the ability to define login restrictions on a per-machine basis. Machine-specific netgroup definitions are the other possibility to deal with the policy change outlined above. In this scenario, the /etc/master.passwd of each box contains two lines starting with +. The first of them adds a netgroup with the accounts allowed to login onto this machine, the second one adds all other accounts with /sbin/nologin as shell. It is a good idea to use the ALL-CAPS version of the machine name as the name of the netgroup. In other words, the lines should look like this: +@BOXNAME::::::::: +:::::::::/sbin/nologin Once you have completed this task for all your machines, you will not have to modify the local versions of /etc/master.passwd ever again. All further changes can be handled by modifying the NIS map. Here is an example of a possible netgroup map for this scenario with some additional goodies. # Define groups of users first IT_EMP (,alpha,test-domain) (,beta,test-domain) IT_APP (,charlie,test-domain) (,delta,test-domain) DEPT1 (,echo,test-domain) (,foxtrott,test-domain) DEPT2 (,golf,test-domain) (,hotel,test-domain) DEPT3 (,india,test-domain) (,juliet,test-domain) ITINTERN (,kilo,test-domain) (,lima,test-domain) D_INTERNS (,able,test-domain) (,baker,test-domain) # # Now, define some groups based on roles USERS DEPT1 DEPT2 DEPT3 BIGSRV IT_EMP IT_APP SMALLSRV IT_EMP IT_APP ITINTERN USERBOX IT_EMP ITINTERN USERS # # And a groups for a special tasks # Allow echo and golf to access our anti-virus-machine SECURITY IT_EMP (,echo,test-domain) (,golf,test-domain) # # machine-based netgroups # Our main servers WAR BIGSRV FAMINE BIGSRV # User india needs access to this server POLLUTION BIGSRV (,india,test-domain) # # This one is really important and needs more access restrictions DEATH IT_EMP # # The anti-virus-machine mentioned above ONE SECURITY # # Restrict a machine to a single user TWO (,hotel,test-domain) # [...more groups to follow] If you are using some kind of database to manage your user accounts, you should be able to create the first part of the map with your database's report tools. This way, new users will automatically have access to the boxes. One last word of caution: It may not always be advisable to use machine-based netgroups. If you are deploying a couple of dozen or even hundreds of identical machines for student labs, you should use role-based netgroups instead of machine-based netgroups to keep the size of the NIS map within reasonable limits. Important Things to Remember There are still a couple of things that you will need to do differently now that you are in an NIS environment. Every time you wish to add a user to the lab, you must add it to the master NIS server only, and you must remember to rebuild the NIS maps. If you forget to do this, the new user will not be able to login anywhere except on the NIS master. For example, if we needed to add a new user jsmith to the lab, we would: &prompt.root; pw useradd jsmith &prompt.root; cd /var/yp &prompt.root; make test-domain You could also run adduser jsmith instead of pw useradd jsmith. Keep the administration accounts out of the NIS maps. You do not want to be propagating administrative accounts and passwords to machines that will have users that should not have access to those accounts. Keep the NIS master and slave secure, and minimize their downtime. If somebody either hacks or simply turns off these machines, they have effectively rendered many people without the ability to login to the lab. This is the chief weakness of any centralized administration system, and it is probably the most important weakness. If you do not protect your NIS servers, you will have a lot of angry users! NIS v1 Compatibility FreeBSD's ypserv has some support for serving NIS v1 clients. FreeBSD's NIS implementation only uses the NIS v2 protocol, however other implementations include support for the v1 protocol for backwards compatibility with older systems. The ypbind daemons supplied with these systems will try to establish a binding to an NIS v1 server even though they may never actually need it (and they may persist in broadcasting in search of one even after they receive a response from a v2 server). Note that while support for normal client calls is provided, this version of ypserv does not handle v1 map transfer requests; consequently, it cannot be used as a master or slave in conjunction with older NIS servers that only support the v1 protocol. Fortunately, there probably are not any such servers still in use today. NIS Servers that are also NIS Clients Care must be taken when running ypserv in a multi-server domain where the server machines are also NIS clients. It is generally a good idea to force the servers to bind to themselves rather than allowing them to broadcast bind requests and possibly become bound to each other. Strange failure modes can result if one server goes down and others are dependent upon it. Eventually all the clients will time out and attempt to bind to other servers, but the delay involved can be considerable and the failure mode is still present since the servers might bind to each other all over again. You can force a host to bind to a particular server by running ypbind with the flag. If you do not want to do this manually each time you reboot your NIS server, you can add the following lines to your /etc/rc.conf: nis_client_enable="YES" # run client stuff as well nis_client_flags="-S NIS domain,server" See &man.ypbind.8; for further information. libscrypt v.s. libdescrypt NIS crypto library One of the most common issues that people run into when trying to implement NIS is crypt library compatibility. If your NIS server is using the DES crypt libraries, it will only support clients that are using DES as well. To check which one your server and clients are using look at the symlinks in /usr/lib. If the machine is configured to use the DES libraries, it will look something like this: &prompt.user; ls -l /usr/lib/*crypt* lrwxrwxrwx 1 root wheel 13 Jul 15 08:55 libcrypt.a@ -> libdescrypt.a lrwxrwxrwx 1 root wheel 14 Jul 15 08:55 libcrypt.so@ -> libdescrypt.so lrwxrwxrwx 1 root wheel 16 Jul 15 08:55 libcrypt.so.2@ -> libdescrypt.so.2 lrwxrwxrwx 1 root wheel 15 Jul 15 08:55 libcrypt_p.a@ -> libdescrypt_p.a -r--r--r-- 1 root wheel 13018 Nov 8 14:27 libdescrypt.a lrwxr-xr-x 1 root wheel 16 Nov 8 14:27 libdescrypt.so@ -> libdescrypt.so.2 -r--r--r-- 1 root wheel 12965 Nov 8 14:27 libdescrypt.so.2 -r--r--r-- 1 root wheel 14750 Nov 8 14:27 libdescrypt_p.a If the machine is configured to use the standard FreeBSD MD5 crypt libraries they will look something like this: &prompt.user; ls -l /usr/lib/*crypt* lrwxrwxrwx 1 root wheel 13 Jul 15 08:55 libcrypt.a@ -> libscrypt.a lrwxrwxrwx 1 root wheel 14 Jul 15 08:55 libcrypt.so@ -> libscrypt.so lrwxrwxrwx 1 root wheel 16 Jul 15 08:55 libcrypt.so.2@ -> libscrypt.so.2 lrwxrwxrwx 1 root wheel 15 Jul 15 08:55 libcrypt_p.a@ -> libscrypt_p.a -r--r--r-- 1 root wheel 6194 Nov 8 14:27 libscrypt.a lrwxr-xr-x 1 root wheel 14 Nov 8 14:27 libscrypt.so@ -> libscrypt.so.2 -r--r--r-- 1 root wheel 7579 Nov 8 14:27 libscrypt.so.2 -r--r--r-- 1 root wheel 6684 Nov 8 14:27 libscrypt_p.a If you have trouble authenticating on an NIS client, this is a pretty good place to start looking for possible problems. If you want to deploy an NIS server for a heterogenous network, you will probably have to use DES on all systems because it is the lowest common standard. Greg Sutter Written by DHCP What Is DHCP? Dynamic Host Configuration Protocol DHCP Internet Software Consortium (ISC) DHCP, the Dynamic Host Configuration Protocol, describes the means by which a system can connect to a network and obtain the necessary information for communication upon that network. FreeBSD uses the ISC (Internet Software Consortium) DHCP implementation, so all implementation-specific information here is for use with the ISC distribution. What this Section Covers This section describes both the client-side and server-side components of the ISC DHCP system. The client-side program, dhclient, comes integrated within FreeBSD, and the server-side portion is available from the net/isc-dhcp3 port. The &man.dhclient.8;, &man.dhcp-options.5;, and &man.dhclient.conf.5; manual pages, in addition to the references below, are useful resources. How It Works UDP When dhclient, the DHCP client, is executed on the client machine, it begins broadcasting requests for configuration information. By default, these requests are on UDP port 68. The server replies on UDP 67, giving the client an IP address and other relevant network information such as netmask, router, and DNS servers. All of this information comes in the form of a DHCP lease and is only valid for a certain time (configured by the DHCP server maintainer). In this manner, stale IP addresses for clients no longer connected to the network can be automatically reclaimed. DHCP clients can obtain a great deal of information from the server. An exhaustive list may be found in &man.dhcp-options.5;. FreeBSD Integration FreeBSD fully integrates the ISC DHCP client, dhclient. DHCP client support is provided within both the installer and the base system, obviating the need for detailed knowledge of network configurations on any network that runs a DHCP server. dhclient has been included in all FreeBSD distributions since 3.2. sysinstall DHCP is supported by sysinstall. When configuring a network interface within sysinstall, the first question asked is, Do you want to try DHCP configuration of this interface? Answering affirmatively will execute dhclient, and if successful, will fill in the network configuration information automatically. There are two things you must do to have your system use DHCP upon startup: DHCP requirements Make sure that the bpf device is compiled into your kernel. To do this, add pseudo-device bpf to your kernel configuration file, and rebuild the kernel. For more information about building kernels, see . The bpf device is already part of the GENERIC kernel that is supplied with FreeBSD, so if you do not have a custom kernel, you should not need to create one in order to get DHCP working. For those who are particularly security conscious, you should be warned that bpf is also the device that allows packet sniffers to work correctly (although they still have to be run as root). bpf is required to use DHCP, but if you are very sensitive about security, you probably should not add bpf to your kernel in the expectation that at some point in the future you will be using DHCP. Edit your /etc/rc.conf to include the following: ifconfig_fxp0="DHCP" Be sure to replace fxp0 with the designation for the interface that you wish to dynamically configure. If you are using a different location for dhclient, or if you wish to pass additional flags to dhclient, also include the following (editing as necessary): dhcp_program="/sbin/dhclient" dhcp_flags="" DHCP server The DHCP server, dhcpd, is included as part of the net/isc-dhcp3 port in the ports collection. This port contains the full ISC DHCP distribution, consisting of client, server, relay agent and documentation. Files DHCP configuration files /etc/dhclient.conf dhclient requires a configuration file, /etc/dhclient.conf. Typically the file contains only comments, the defaults being reasonably sane. This configuration file is described by the &man.dhclient.conf.5; manual page. /sbin/dhclient dhclient is statically linked and resides in /sbin. The &man.dhclient.8; manual page gives more information about dhclient. /sbin/dhclient-script dhclient-script is the FreeBSD-specific DHCP client configuration script. It is described in &man.dhclient-script.8;, but should not need any user modification to function properly. /var/db/dhclient.leases The DHCP client keeps a database of valid leases in this file, which is written as a log. &man.dhclient.leases.5; gives a slightly longer description. Further Reading The DHCP protocol is fully described in RFC 2131. An informational resource has also been set up at dhcp.org. Ceri Davies Written by
ceri@FreeBSD.org
Installing And Configuring A DHCP Server What this Section Covers This section provides information on how to configure a FreeBSD system to act as a DHCP server using the ISC (Internet Software Consortium) implementation of the DHCP suite. The server portion of the suite is not provided as part of FreeBSD, and so you will need to install the net/isc-dhcp3 port to provide this service. See for more information on using the ports collection. DHCP Server Installation DHCP installation In order to configure your FreeBSD system as a DHCP server, you will need to ensure that the &man.bpf.4; device is compiled into your kernel. To do this, add pseudo-device bpf to your kernel configuration file, and rebuild the kernel. For more information about building kernels, see . The bpf device is already part of the GENERIC kernel that is supplied with FreeBSD, so you do not need to create a custom kernel in order to get DHCP working. Those who are particularly security conscious should note that bpf is also the device that allows packet sniffers to work correctly (although such programs still need privileged access). bpf is required to use DHCP, but if you are very sensitive about security, you probably should not include bpf in your kernel purely because you expect to use DHCP at some point in the future. The next thing that you will need to do is edit the sample dhcpd.conf which was installed by the net/isc-dhcp3 port. By default, this will be /usr/local/etc/dhcpd.conf.sample, and you should copy this to /usr/local/etc/dhcpd.conf before proceeding to make changes. Configuring the DHCP Server DHCP configuration dhcpd.conf dhcpd.conf is comprised of declarations regarding subnets and hosts, and is perhaps most easily explained using an example : option domain-name "example.com"; option domain-name-servers 192.168.4.100; option subnet-mask 255.255.255.0; default-lease-time 3600; max-lease-time 86400; ddns-update-style none; subnet 192.168.4.0 netmask 255.255.255.0 { range 192.168.4.129 192.168.4.254; option routers 192.168.4.1; } host mailhost { hardware ethernet 02:03:04:05:06:07; fixed-address mailhost.example.com; } This option specifies the domain that will be provided to clients as the default search domain. See &man.resolv.conf.5; for more information on what this means. This option specifies a comma separated list of DNS servers that the client should use. The netmask that will be provided to clients. A client may request a specific length of time that a lease will be valid. Otherwise the server will assign a lease with this expiry value (in seconds). This is the maximum length of time that the server will lease for. Should a client request a longer lease, a lease will be issued, although it will only be valid for max-lease-time seconds. This option specifies whether the DHCP server should attempt to update DNS when a lease is accepted or released. In the ISC implementation, this option is required. This denotes which IP addresses should be used in the pool reserved for allocating to clients. IP addresses between, and including, the ones stated are handed out to clients. Declares the default gateway that will be provided to clients. The hardware MAC address of a host (so that the DHCP server can recognise a host when it makes a request). Specifies that the host should always be given the same IP address. Note that a hostname is OK here, since the DHCP server will resolve the hostname itself before returning the lease information. Once you have finished writing your dhcpd.conf, you can proceed to start the server by issuing the following command: &prompt.root; /usr/local/etc/rc.d/isc-dhcpd.sh start Should you need to make changes to the configuration of your server in the future, it is important to note that sending a SIGHUP signal to dhcpd does not result in the configuration being reloaded, as it does with most daemons. You will need to send a SIGTERM signal to stop the process, and then restart it using the command above. Files DHCP configuration files /usr/local/sbin/dhcpd dhcpd is statically linked and resides in /usr/local/sbin. The dhcpd(8) manual page installed with the port gives more information about dhcpd. /usr/local/etc/dhcpd.conf dhcpd requires a configuration file, /usr/local/etc/dhcpd.conf before it will start providing service to clients. This file needs to contain all the information that should be provided to clients that are being serviced, along with information regarding the operation of the server. This configuration file is described by the dhcpd.conf(5) manual page installed by the port. /var/db/dhcpd.leases The DHCP server keeps a database of leases it has issued in this file, which is written as a log. The manual page dhcpd.leases(5), installed by the port gives a slightly longer description. /usr/local/sbin/dhcrelay dhcrelay is used in advanced environments where one DHCP server forwards a request from a client to another DHCP server on a separate network. The dhcrelay(8) manual page provided with the port contains more detail.
Chern Lee Contributed by DNS Overview BIND FreeBSD utilizes, by default, a version of BIND (Berkeley Internet Name Domain), which is the most common implementation of the DNS protocol. DNS is the protocol through which names are mapped to IP addresses, and vice versa. For example, a query for www.FreeBSD.org will receive a reply with the IP address of The FreeBSD Project's web server, whereas, a query for ftp.FreeBSD.org will return the IP address of the corresponding FTP machine. Likewise, the opposite can happen. A query for an IP address can resolve its hostname. It is not necessary to run a name server to perform DNS lookups on a system. DNS DNS is coordinated across the Internet through a somewhat complex system of authoritative root name servers, and other smaller-scale name servers who host and cache individual domain information. This document refers to BIND 8.x, as it is the stable version used in FreeBSD. BIND 9.x in FreeBSD can be installed through the net/bind9 port. RFC1034 and RFC1035 dictates the DNS protocol. Currently, BIND is maintained by the Internet Software Consortium (www.isc.org) Terminology To understand this document, some terms related to DNS must be understood. Term Definition forward DNS mapping of hostnames to IP addresses origin refers to the domain covered for the particular zone file named, bind, name server common names for the BIND name server package within FreeBSD resolver resolver a system process through which a machine queries a name server for zone information reverse DNS reverse DNS the opposite of forward DNS, mapping of IP addresses to hostnames root zone root zone literally, a ., refers to the root, or beginning zone. All zones fall under this, as do all files in fall under the root directory. It is the beginning of the Internet zone hierarchy. zone Each individual domain, subdomain, or area dictated by DNS zones examples Examples of zones: . is the root zone org. is a zone under the root zone example.org is a zone under the org. zone foo.example.org. is a subdomain, a zone under the example.org. zone 1.2.3.in-addr.arpa is a zone referencing all IP addresses which fall under the 3.2.1.* IP space. As one can see, the more specific part of a hostname appears to its left. For example, example.org. is more specific than org., as org. is more specific than the root zone. The layout of each part of a hostname is much like a filesystem: the /dev directory falls within the root, and so on. Reasons to Run a Name Server Name servers usually come in two forms: an authoritative name server, and a caching name server. An authoritative name server is needed when: one wants to serve DNS information to the world, replying authoritatively to queries. a domain, such as example.org, is registered and IP addresses need to be assigned to hostnames under it. an IP address block requires reverse DNS entries (IP to hostname). a backup name server, called a slave, must reply to queries when the primary is down or inaccessible. A caching name server is needed when: a local DNS server may cache and respond more quickly than querying an outside name server. a reduction in overall network traffic is desired (DNS traffic has been measured to account for 5% or more of total Internet traffic). When one queries for www.FreeBSD.org, the resolver usually queries the uplink ISP's name server, and retrieves the reply. With a local, caching DNS server, the query only has to be made once to the outside world by the caching DNS server. Every additional query will not have to look to the outside of the local network, since the information is cached locally. How It Works In FreeBSD, the BIND daemon is called named for obvious reasons. File Description named the BIND daemon ndc name daemon control program /etc/namedb directory where BIND zone information resides /etc/namedb/named.conf daemon configuration file Zone files are usually contained within the /etc/namedb directory, and contain the DNS zone information served by the name server. Starting BIND BIND starting Since BIND is installed by default, configuring it all is relatively simple. To ensure the named daemon is started at boot, put the following modifications in /etc/rc.conf: named_enable="YES" To start the daemon manually (after configuring it) &prompt.root; ndc start Configuration Files BIND configuration files make-localhost Be sure to: &prompt.root; cd /etc/namedb &prompt.root; sh make-localhost to properly create the local reverse DNS zone file in /etc/namedb/localhost.rev. <filename>/etc/namedb/named.conf</filename> // $FreeBSD$ // // Refer to the named(8) manual page for details. If you are ever going // to setup a primary server, make sure you've understood the hairy // details of how DNS is working. Even with simple mistakes, you can // break connectivity for affected parties, or cause huge amount of // useless Internet traffic. options { directory "/etc/namedb"; // In addition to the "forwarders" clause, you can force your name // server to never initiate queries of its own, but always ask its // forwarders only, by enabling the following line: // // forward only; // If you've got a DNS server around at your upstream provider, enter // its IP address here, and enable the line below. This will make you // benefit from its cache, thus reduce overall DNS traffic in the Internet. /* forwarders { 127.0.0.1; }; */ Just as the comment says, to benefit from an uplink's cache, forwarders can be enabled here. Under normal circumstances, a name server will recursively query the Internet looking at certain name servers until it finds the answer it is looking for. Having this enabled will have it query the uplink's name server (or name server provided) first, taking advantage of its cache. If the uplink name server in question is a heavily trafficked, fast name server, enabling this may be worthwhile. 127.0.0.1 will not work here. Change this IP address to a name server at your uplink. /* * If there is a firewall between you and name servers you want * to talk to, you might need to uncomment the query-source * directive below. Previous versions of BIND always asked * questions using port 53, but BIND 8.1 uses an unprivileged * port by default. */ // query-source address * port 53; /* * If running in a sandbox, you may have to specify a different * location for the dumpfile. */ // dump-file "s/named_dump.db"; }; // Note: the following will be supported in a future release. /* host { any; } { topology { 127.0.0.0/8; }; }; */ // Setting up secondaries is way easier and the rough picture for this // is explained below. // // If you enable a local name server, don't forget to enter 127.0.0.1 // into your /etc/resolv.conf so this server will be queried first. // Also, make sure to enable it in /etc/rc.conf. zone "." { type hint; file "named.root"; }; zone "0.0.127.IN-ADDR.ARPA" { type master; file "localhost.rev"; }; zone "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.INT" { type master; file "localhost.rev"; }; // NB: Do not use the IP addresses below, they are faked, and only // serve demonstration/documentation purposes! // // Example secondary config entries. It can be convenient to become // a secondary at least for the zone where your own domain is in. Ask // your network administrator for the IP address of the responsible // primary. // // Never forget to include the reverse lookup (IN-ADDR.ARPA) zone! // (This is the first bytes of the respective IP address, in reverse // order, with ".IN-ADDR.ARPA" appended.) // // Before starting to setup a primary zone, better make sure you fully // understand how DNS and BIND works, however. There are sometimes // unobvious pitfalls. Setting up a secondary is comparably simpler. // // NB: Don't blindly enable the examples below. :-) Use actual names // and addresses instead. // // NOTE!!! FreeBSD runs bind in a sandbox (see named_flags in rc.conf). // The directory containing the secondary zones must be write accessible // to bind. The following sequence is suggested: // // mkdir /etc/namedb/s // chown bind:bind /etc/namedb/s // chmod 750 /etc/namedb/s For more information on running BIND in a sandbox, see Running named in a sandbox. /* zone "example.com" { type slave; file "s/example.com.bak"; masters { 192.168.1.1; }; }; zone "0.168.192.in-addr.arpa" { type slave; file "s/0.168.192.in-addr.arpa.bak"; masters { 192.168.1.1; }; }; */ In named.conf, these are examples of slave entries for a forward and reverse zone. For each new zone served, a new zone entry must be added to named.conf For example, the simplest zone entry for example.org can look like: zone "example.org" { type master; file "example.org"; }; The zone is a master, as indicated by the statement, holding its zone information in /etc/namedb/example.org indicated by the statement. zone "example.org" { type slave; file "example.org"; }; In the slave case, the zone information is transferred from the master name server for the particular zone, and saved in the file specified. If and when the master server dies or is unreachable, the slave name server will have the transferred zone information and will be able to serve it. Zone Files An example master zone file for example.org (existing within /etc/namedb/example.org) is as follows: $TTL 3600 example.org. IN SOA ns1.example.org. admin.example.org. ( 5 ; Serial 10800 ; Refresh 3600 ; Retry 604800 ; Expire 86400 ) ; Minimum TTL ; DNS Servers @ IN NS ns1.example.org. @ IN NS ns2.example.org. ; Machine Names localhost IN A 127.0.0.1 ns1 IN A 3.2.1.2 ns2 IN A 3.2.1.3 mail IN A 3.2.1.10 @ IN A 3.2.1.30 ; Aliases www IN CNAME @ ; MX Record @ IN MX 10 mail.example.org. Note that every hostname ending in a . is an exact hostname, whereas everything without a trailing . is referenced to the origin. For example, www is translated into www + origin. In our fictitious zone file, our origin is example.org., so www would translate to www.example.org. The format of a zone file follows: recordname IN recordtype value DNS records The most commonly used DNS records: SOA start of zone authority NS an authoritative name server A A host address CNAME the canonical name for an alias MX mail exchanger PTR a domain name pointer (used in reverse DNS) example.org. IN SOA ns1.example.org. admin.example.org. ( 5 ; Serial 10800 ; Refresh after 3 hours 3600 ; Retry after 1 hour 604800 ; Expire after 1 week 86400 ) ; Minimum TTL of 1 day example.org. the domain name, also the origin for this zone file. ns1.example.org. the primary/authoritative name server for this zone admin.example.org. the responsible person for this zone, email address with @ replaced. (admin@example.org becomes admin.example.org) 5 the serial number of the file. this must be incremented each time the zone file is modified. Nowadays, many admins prefer a yyyymmddrr format for the serial number. 2001041002 would mean last modified 04/10/2001, the latter 02 being the second time the zone file has been modified this day. The serial number is important as it alerts slave name servers for a zone when it is updated. @ IN NS ns1.example.org. This is an NS entry. Every name server that is going to reply authoritatively for the zone must have one of these entries. The @ as seen here could have been example.org. The @ translates to the origin. localhost IN A 127.0.0.1 ns1 IN A 3.2.1.2 ns2 IN A 3.2.1.3 mail IN A 3.2.1.10 @ IN A 3.2.1.30 The A record indicates machine names. As seen above, ns1.example.org would resolve to 3.2.1.2. Again, the origin symbol, @, is used here, thus meaning example.org would resolve to 3.2.1.30. www IN CNAME @ The canonical name record is usually used for giving aliases to a machine. In the example, www is aliased to the machine addressed to the origin, or example.org (3.2.1.30). CNAMEs can be used to provide alias hostnames, or round robin one hostname among multiple machines. @ IN MX 10 mail.example.org. The MX record indicates which mail servers are responsible for handling incoming mail for the zone. mail.example.org is the hostname of the mail server, and 10 being the priority of that mail server. One can have several mail servers, with priorities of 3, 2, 1. A mail server attempting to deliver to example.org would first try the highest priority MX, then the second highest, etc, until the mail can be properly delivered. For in-addr.arpa zone files (reverse DNS), the same format is used, except with PTR entries instead of A or CNAME. $TTL 3600 1.2.3.in-addr.arpa. IN SOA ns1.example.org. admin.example.org. ( 5 ; Serial 10800 ; Refresh 3600 ; Retry 604800 ; Expire 3600 ) ; Minimum @ IN NS ns1.example.org. @ IN NS ns2.example.org. 2 IN PTR ns1.example.org. 3 IN PTR ns2.example.org. 10 IN PTR mail.example.org. 30 IN PTR example.org. This file gives the proper IP address to hostname mappings of our above fictitious domain. Caching Name Server BIND caching name server A caching name server is a name server that is not authoritative for any zones. It simply asks queries of its own, and remembers them for later use. To set one up, just configure the name server as usual, omitting any inclusions of zones. Ceri Davies Contributed by Running named in a Sandbox BIND running in a sandbox chroot For added security you may want to run &man.named.8; as an unprivileged user, and configure it to &man.chroot.8; into a sandbox directory. This makes everything outside of the sandbox inaccessible to the named daemon. Should named be compromised, this will help to reduce the damage that can be caused. By default, FreeBSD has a user and a group called bind, intended for this use. Various people would recommend that instead of configuring named to chroot, you should run named inside a &man.jail.8;. This section does not attempt to cover this situation. Since named will not be able to access anything outside of the sandbox (such as shared libraries, log sockets, and so on), there are a number of steps that need to be followed in order to allow named to function correctly. In the following checklist, it is assumed that the path to the sandbox is /etc/namedb and that you have made no prior modifications to the contents of this directory. Perform the following steps as root. Create all directories that named expects to see: &prompt.root; cd /etc/namedb &prompt.root; mkdir -p bin dev etc var/tmp var/run master slave &prompt.root; chown bind:bind slave var/* named only needs write access to these directories, so that is all we give it. Rearrange and create basic zone and configuration files: &prompt.root; cp /etc/localtime etc &prompt.root; mv named.conf etc && ln -sf etc/named.conf &prompt.root; mv named.root master &prompt.root; sh make-localhost && mv localhost.rev localhost-v6.rev master &prompt.root; cat > master/named.localhost $ORIGIN localhost. $TTL 6h @ IN SOA localhost. postmaster.localhost. ( 1 ; serial 3600 ; refresh 1800 ; retry 604800 ; expiration 3600 ) ; minimum IN NS localhost. IN A 127.0.0.1 ^D This allows named to log the correct time to &man.syslogd.8; Build a statically linked copy of named-xfer, and copy it into the sandbox: &prompt.root; cd /usr/src/lib/libisc && make clean all &prompt.root; cd /usr/src/lib/libbind && make clean all &prompt.root; cd /usr/src/libexec/named-xfer && make NOSHARED=yes all &prompt.root; cp named-xfer /etc/namedb/bin && chmod 555 /etc/namedb/bin/named-xfer This step has been reported to fail occasionally. If this happens to you, then issue the command: &prompt.root; cd /usr/src && make cleandir && make cleandir This will clean out any cruft from your source tree, and retrying the steps above should then work. Make a dev/null that named can see and write to: &prompt.root; cd /etc/namedb/dev && mknod null c 2 2 &prompt.root; chmod 666 null Symlink /var/run/ndc to /etc/namedb/var/run/ndc: &prompt.root; ln -sf /etc/namedb/var/run/ndc /var/run/ndc This simply avoids having to specify the option to &man.ndc.8; every time you run it. Since the contents of /var/run are deleted on boot, if this is something that you find useful you may wish to add this command to root's crontab, making use of the option. See &man.crontab.5; for more information regarding this. Configure &man.syslogd.8; to create an extra log socket that named can write to. To do this, add -l /etc/namedb/dev/log to the syslogd_flags variable in /etc/rc.conf. Arrange to have named start and chroot itself to the sandbox by adding the following to /etc/rc.conf: named_enable="YES" named_flags="-u bind -g bind -t /etc/namedb /etc/named.conf" Note that the configuration file /etc/named.conf is denoted by a full pathname relative to the sandbox, i.e. in the line above, the file referred to is actually /etc/namedb/etc/named.conf. The next step is to edit /etc/namedb/etc/named.conf so that named knows which zones to load and where to find them on the disk. There follows a commented example (anything not specifically commented here is no different from the setup for a DNS server not running in a sandbox): options { directory "/"; named-xfer "/bin/named-xfer"; version ""; // Don't reveal BIND version query-source address * port 53; }; // ndc control socket controls { unix "/var/run/ndc" perm 0600 owner 0 group 0; }; // Zones follow: zone "localhost" IN { type master; file "master/named.localhost"; allow-transfer { localhost; }; notify no; }; zone "0.0.127.in-addr.arpa" IN { type master; file "master/localhost.rev"; allow-transfer { localhost; }; notify no; }; zone "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.int" { type master; file "master/localhost-v6.rev"; allow-transfer { localhost; }; notify no; }; zone "." IN { type hint; file "master/named.root"; }; zone "private.example.net" in { type master; file "master/private.example.net.db"; allow-transfer { 192.168.10.0/24; }; }; zone "10.168.192.in-addr.arpa" in { type slave; masters { 192.168.10.2; }; file "slave/192.168.10.db"; }; The directory statement is specified as /, since all files that named needs are within this directory (recall that this is equivalent to a normal user's /etc/namedb. Specifies the full path to the named-xfer binary (from named's frame of reference). This is necessary since named is compiled to look for named-xfer in /usr/libexec by default. Specifies the filename (relative to the directory statement above) where named can find the zonefile for this zone. Specifies the filename (relative to the directory statement above) where named should write a copy of the zonefile for this zone after successfully transferring it from the master server. This is why we needed to change the ownership of the directory slave to bind in the setup stages above. After completing the steps above, either reboot your server or restart &man.syslogd.8; and start &man.named.8;, making sure to use the new options specified in syslogd_flags and named_flags. You should now be running a sandboxed copy of named! Security Although BIND is the most common implementation of DNS, there is always the issue of security. Possible and exploitable security holes are sometimes found. It is a good idea to subscribe to CERT and freebsd-security-notifications to stay up to date with the current Internet and FreeBSD security issues. If a problem arises, keeping sources up to date and having a fresh build of named would not hurt. Further Reading BIND/named manual pages: &man.ndc.8; &man.named.8; &man.named.conf.5; Official ISC Bind Page BIND FAQ O'Reilly DNS and BIND 4th Edition RFC1034 - Domain Names - Concepts and Facilities RFC1035 - Domain Names - Implementation and Specification Tom Hukins Contributed by NTP NTP Overview Over time, a computer's clock is prone to drift. As time passes, the computer's clock becomes less accurate. NTP (Network Time Protocol) is one way to ensure your clock is right. Many Internet services rely on, or greatly benefit from, computers' clocks being accurate. For example, a Web server may receive requests to send a file if it has modified since a certain time. Services such as &man.cron.8; run commands at a given time. If the clock is inaccurate, these commands may not run when expected. NTP ntpd FreeBSD ships with the &man.ntpd.8; NTP server which can be used to query other NTP servers to set the clock on your machine or provide time services to others. Choosing Appropriate NTP Servers NTP choosing servers In order to synchronize your clock, you will need to find one or more NTP servers to use. Your network administrator or ISP may have setup an NTP server for this purpose—check their documentation to see if this is the case. There is a list of publicly accessible NTP servers which you can use to find an NTP server near to you. Make sure you are aware of the policy for any servers you choose, and ask for permission if required. Choosing several unconnected NTP servers is a good idea in case one of the servers you are using becomes unreachable or its clock is unreliable. &man.ntpd.8; uses the responses it receives from other servers intelligently—it will favor unreliable servers less than reliable ones. Configuring Your Machine NTP configuration Basic Configuration ntpdate If you only wish to synchronize your clock when the machine boots up, you can use &man.ntpdate.8;. This may be appropriate for some desktop machines which are frequently rebooted and only require infrequent synchronization, but most machines should run &man.ntpd.8;. Using &man.ntpdate.8; at boot time is also a good idea for machines that run &man.ntpd.8;. &man.ntpd.8; changes the clock gradually, whereas &man.ntpdate.8; sets the clock, no matter how great the difference between a machine's current clock setting and the correct time. To enable &man.ntpdate.8; at boot time, add ntpdate_enable="YES" to /etc/rc.conf. You will also need to specify all servers you wish to synchronize with and any flags to be passed to &man.ntpdate.8; in ntpdate_flags. NTP ntp.conf General Configuration NTP is configured by the /etc/ntp.conf file in the format described in &man.ntp.conf.5;. Here is a simple example: server ntplocal.example.com prefer server timeserver.example.org server ntp2a.example.net driftfile /var/db/ntp.drift The server option specifies which servers are to be used, with one server listed on each line. If a server is specified with the prefer argument, as with ntplocal.example.com, that server is preferred over other servers. A response from a preferred server will be discarded if it differs significantly from other servers' responses, otherwise it will be used without any consideration to other responses. The prefer argument is normally used for NTP servers that are known to be highly accurate, such as those with special time monitoring hardware. The driftfile option specifies which file is used to store the system clock's frequency offset. &man.ntpd.8; uses this to automatically compensate for the clock's natural drift, allowing it to maintain a reasonably correct setting even if it is cut off from all external time sources for a period of time. The driftfile option specifies which file is used to store information about previous responses from the NTP servers you are using. This file contains internal information for NTP. It should not be modified by any other process. Controlling Access to Your Server By default, your NTP server will be accessible to all hosts on the Internet. The restrict option in &man.ntp.conf.5; allows you to control which machines can access your server. If you want to deny all machines from accessing your NTP server, add the line restrict default ignore to /etc/ntp.conf. If you only want to allow machines within your own network to synchronize their clocks with your server, but ensure they are not allowed to configure the server or used as peers to synchronize against, add restrict 192.168.1.0 mask 255.255.255.0 notrust nomodify notrap instead, where 192.168.1.0 is an IP address on your network and 255.255.255.0 is your network's netmask. /etc/ntp.conf can contain multiple restrict options. For more details, see the Access Control Support subsection of &man.ntp.conf.5;. Running the NTP Server To ensure the NTP server is started at boot time, add the line xntpd_enable="YES" to /etc/rc.conf. If you wish to pass additional flags to &man.ntpd.8; edit the xntpd_flags parameter in /etc/rc.conf. To start the server without rebooting your machine, run ntpd being sure to specify any additional parameters from xntpd_flags in /etc/rc.conf. For example: &prompt.root; ntpd -p /var/run/ntpd.pid Using &man.ntpd.8; with a temporary Internet connection ntpd does not need a permanent connection to the Internet to function properly. However, if you have a temporary connection that is configured to dial out on demand, it is a good idea to prevent NTP traffic from triggering a dial out or keeping the connection alive. If you are using user PPP, you can use filter directives in /etc/ppp/ppp.conf. For example: set filter dial 0 deny udp src eq 123 # Prevent NTP traffic from initiating dial out set filter dial 1 permit 0 0 set filter alive 0 deny udp src eq 123 # Prevent incoming NTP traffic from keeping the connection open set filter alive 1 deny udp dst eq 123 # Prevent outgoing NTP traffic from keeping the connection open set filter alive 2 permit 0/0 0/0 For more details see the PACKET FILTERING section in &man.ppp.8; and the examples in /usr/share/examples/ppp/. Some Internet access providers block low-numbered ports, preventing NTP from functioning since replies never reach your machine. Further Information Documentation for the NTP server can be found in /usr/share/doc/ntp/ in HTML format. Chern Lee Contributed by Network Address Translation Overview natd FreeBSD's Network Address Translation daemon, commonly known as &man.natd.8; is a daemon that accepts incoming raw IP packets, changes the source to the local machine and re-injects these packets back into the outgoing IP packet stream. natd does this by changing the source IP address and port such that when data is received back, it is able to determine the original location of the data and forward it back to its original requester. Internet connection sharing IP masquerading The most common use of NAT is to perform what is commonly known as Internet Connection Sharing. Setup Due to the diminishing IP space in IPv4, and the increased number of users on high-speed consumer lines such as cable or DSL, people are increasingly in need of an Internet Connection Sharing solution. The ability to connect several computers online through one connection and IP address makes &man.natd.8; a reasonable choice. Most commonly, a user has a machine connected to a cable or DSL line with one IP address and wishes to use this one connected computer to provide Internet access to several more over a LAN. To do this, the FreeBSD machine on the Internet must act as a gateway. This gateway machine must have two NICs--one for connecting to the Internet router, the other connecting to a LAN. All the machines on the LAN are connected through a hub or switch. _______ __________ ________ | | | | | | | Hub |-----| Client B |-----| Router |----- Internet |_______| |__________| |________| | ____|_____ | | | Client A | |__________| Network Layout A setup like this is commonly used to share an Internet connection. One of the LAN machines is connected to the Internet. The rest of the machines access the Internet through that gateway machine. kernel configuration Configuration The following options must be in the kernel configuration file: options IPFIREWALL options IPDIVERT Additionally, at choice, the following may also be suitable: options IPFIREWALL_DEFAULT_TO_ACCEPT options IPFIREWALL_VERBOSE The following must be in /etc/rc.conf: gateway_enable="YES" firewall_enable="YES" firewall_type="OPEN" natd_enable="YES" natd_interface="fxp0" natd_flags="" gateway_enable="YES" Sets up the machine to act as a gateway. Running sysctl net.inet.ip.forwarding=1 would have the same effect. firewall_enable="YES" Enables the firewall rules in /etc/rc.firewall at boot. firewall_type="OPEN" This specifies a predefined firewall ruleset that allows anything in. See /etc/rc.firewall for additional types. natd_interface="fxp0" Indicates which interface to forward packets through (the interface connected to the Internet). natd_flags="" Any additional configuration options passed to &man.natd.8; on boot. Having the previous options defined in /etc/rc.conf would run natd -interface fxp0 at boot. This can also be run manually. Each machine and interface behind the LAN should be assigned IP address numbers in the private network space as defined by RFC 1918 and have a default gateway of the natd machine's internal IP address. For example, client a and b behind the LAN have IP addresses of 192.168.0.2 and 192.168.0.3, while the natd machine's LAN interface has an IP address of 192.168.0.1. Client a and b's default gateway must be set to that of the natd machine, 192.168.0.1. The natd machine's external, or Internet interface does not require any special modification for natd to work. Port Redirection The drawback with natd is that the LAN clients are not accessible from the Internet. Clients on the LAN can make outgoing connections to the world but cannot receive incoming ones. This presents a problem if trying to run Internet services on one of the LAN client machines. A simple way around this is to redirect selected Internet ports on the natd machine to a LAN client. For example, an IRC server runs on Client A, and a web server runs on Client B. For this to work properly, connections received on ports 6667 (irc) and 80 (web) must be redirected to the respective machines. The -redirect_port must be passed to &man.natd.8; with the proper options. The syntax is as follows: -redirect_port proto targetIP:targetPORT[-targetPORT] [aliasIP:]aliasPORT[-aliasPORT] [remoteIP[:remotePORT[-remotePORT]]] In the above example, the argument should be: -redirect_port tcp 192.168.0.2:6667 6667 -redirect_port tcp 192.168.0.3:80 80 This will redirect the proper tcp ports to the LAN client machines. The -redirect_port argument can be used to indicate port ranges over individual ports. For example, tcp 192.168.0.2:2000-3000 2000-3000 would redirect all connections received on ports 2000 to 3000 to ports 2000 to 3000 on Client A. These options can be used when directly running &man.natd.8; or placed within the natd_flags="" option in /etc/rc.conf. For further configuration options, consult &man.natd.8; Address Redirection address redirection Address redirection is useful if several IP addresses are available, yet they must be on one machine. With this, &man.natd.8; can assign each LAN client its own external IP address. &man.natd.8; then rewrites outgoing packets from the LAN clients with the proper external IP address and redirects all traffic incoming on that particular IP address back to the specific LAN client. This is also known as static NAT. For example, the IP addresses 128.1.1.1, 128.1.1.2, and 128.1.1.3 belong to the natd gateway machine. 128.1.1.1 can be used as the natd gateway machine's external IP address, while 128.1.1.2 and 128.1.1.3 are forwarded back to LAN clients A and B. The -redirect_address syntax is as follows: localIP The internal IP address of the LAN client. publicIP The external IP address corresponding to the LAN client. In the example, this argument would read: Like -redirect_port, these arguments are also placed within natd_flags of /etc/rc.conf. With address redirection, there is no need for port redirection since all data received on a particular IP address is redirected. The external IP addresses on the natd machine must be active and aliased to the external interface. Look at &man.rc.conf.5; to do so. Chern Lee Contributed by inetd <quote>Super-Server</quote> Overview &man.inetd.8; is referred to as the Internet Super-Server because it manages connections for several daemons. Programs that provide network service are commonly known as daemons. inetd serves as a managing server for other daemons. When a connection is received by inetd, it determines which daemon the connection is destined for, spawns the particular daemon and delegates the socket to it. Running one instance of inetd reduces the overall system load as compared to running each daemon individually in stand-alone mode. Primarily, inetd is used to spawn other daemons, but several trivial protocols are handled directly, such as chargen, auth, and daytime. This section will cover the basics in configuring inetd through its command-line options and its configuration file, /etc/inetd.conf. Settings inetd is initialized through the /etc/rc.conf system. The inetd_enable option is set to NO by default, but is often times turned on by sysinstall with the medium security profile. Placing: inetd_enable="YES" or inetd_enable="NO" into /etc/rc.conf can enable or disable inetd starting at boot time. Additionally, different command-line options can be passed to inetd via the inetd_flags option. Command-Line Options inetd synopsis: -d Turn on debugging. -l Turn on logging of successful connections. -w Turn on TCP Wrapping for external services (on by default). -W Turn on TCP Wrapping for internal services which are built into inetd (on by default). -c maximum Specify the default maximum number of simultaneous invocations of each service; the default is unlimited. May be overridden on a per-service basis with the parameter. -C rate Specify the default maximum number of times a service can be invoked from a single IP address in one minute; the default is unlimited. May be overridden on a per-service basis with the parameter. -R rate Specify the maximum number of times a service can be invoked in one minute; the default is 256. A rate of 0 allows an unlimited number of invocations. -a Specify one specific IP address to bind to. Alternatively, a hostname can be specified, in which case the IPv4 or IPv6 address which corresponds to that hostname is used. Usually a hostname is specified when inetd is run inside a &man.jail.8;, in which case the hostname corresponds to the &man.jail.8; environment. When hostname specification is used and both IPv4 and IPv6 bindings are desired, one entry with the appropriate protocol type for each binding is required for each service in /etc/inetd.conf. For example, a TCP-based service would need two entries, one using tcp4 for the protocol and the other using tcp6. -p Specify an alternate file in which to store the process ID. These options can be passed to inetd using the inetd_flags option in /etc/rc.conf. By default, inetd_flags is set to -wW, which turns on TCP wrapping for inetd's internal and external services. For novice users, these parameters usually do not need to be modified or even entered in /etc/rc.conf. An external service is a daemon outside of inetd, which is invoked when a connection is received for it. On the other hand, an internal service is one that inetd has the facility of offering within itself. <filename>inetd.conf</filename> Configuration of inetd is controlled through the /etc/inetd.conf file. When a modification is made to /etc/inetd.conf, inetd can be forced to re-read its configuration file by sending a HangUP signal to the inetd process as shown: Sending <application>inetd</application> a HangUP Signal &prompt.root; kill -HUP `cat /var/run/inetd.pid` Each line of the configuration file specifies an individual daemon. Comments in the file are preceded by a #. The format of /etc/inetd.conf is as follows: service-name socket-type protocol {wait|nowait}[/max-child[/max-connections-per-ip-per-minute]] user[:group][/login-class] server-program server-program-arguments An example entry for the ftpd daemon using IPv4: ftp stream tcp nowait root /usr/libexec/ftpd ftpd -l service-name This is the service name of the particular daemon. It must correspond to a service listed in /etc/services. This determines which port inetd must listen to. If a new service is being created, it must be placed in /etc/services first. socket-type Either stream, dgram, raw, or seqpacket. stream must be used for connection-based, TCP daemons, while dgram is used for daemons utilizing the UDP transport protocol. protocol One of the following: Protocol Explanation tcp, tcp4 TCP IPv4 udp, udp4 UDP IPv4 tcp6 TCP IPv6 udp6 UDP IPv6 tcp46 Both TCP IPv4 and v6 udp46 Both UDP IPv4 and v6 {wait|nowait}[/max-child[/max-connections-per-ip-per-minute]] indicates whether the daemon invoked from inetd is able to handle its own socket or not. socket types must use the wait option, while stream socket daemons, which are usually multi-threaded, should use . usually hands off multiple sockets to a single daemon, while spawns a child daemon for each new socket. The maximum number of child daemons inetd may spawn can be set using the option. If a limit of ten instances of a particular daemon is needed, a /10 would be placed after . In addition to , another option limiting the maximum connections from a single place to a particular daemon can be enabled. does just this. A value of ten here would limit any particular IP address connecting to a particular service to ten attempts per minute. This is useful to prevent intentional or unintentional resource consumption and Denial of Service (DoS) attacks to a machine. In this field, or is mandatory. and are optional. A stream-type multi-threaded daemon without any or limits would simply be: nowait The same daemon with a maximum limit of ten daemons would read: nowait/10 Additionally, the same setup with a limit of twenty connections per IP address per minute and a maximum total limit of ten child daemons would read: nowait/10/20 These options are all utilized by the default settings of the fingerd daemon, as seen here: finger stream tcp nowait/3/10 nobody /usr/libexec/fingerd fingerd -s user The user is the username that the particular daemon should run as. Most commonly, daemons run as the root user. For security purposes, it is common to find some servers running as the daemon user, or the least privileged nobody user. server-program The full path of the daemon to be executed when a connection is received. If the daemon is a service provided by inetd internally, then should be used. server-program-arguments This works in conjunction with by specifying the arguments, starting with argv[0], passed to the daemon on invocation. If mydaemon -d is the command line, mydaemon -d would be the value of . Again, if the daemon is an internal service, use here. Security Depending on the security profile chosen at install, many of inetd's daemons may be enabled by default. If there is no apparent need for a particular daemon, disable it! Place a # in front of the daemon in question, and send a hangup signal to inetd. Some daemons, such as fingerd, may not be desired at all because they provide an attacker with too much information. Some daemons are not security-conscious and have long, or non-existent timeouts for connection attempts. This allows an attacker to slowly send connections to a particular daemon, thus saturating available resources. It may be a good idea to place and limitations on certain daemons. By default, TCP wrapping is turned on. Consult the &man.hosts.access.5; manual page for more information on placing TCP restrictions on various inetd invoked daemons. Miscellaneous daytime, time, echo, discard, chargen, and auth are all internally provided services of inetd. The auth service provides identity (ident, identd) network services, and is configurable to a certain degree. Consult the &man.inetd.8; manual page for more in-depth information. Parallel Line IP (PLIP) PLIP Parallel Line IP PLIP lets us run TCP/IP between parallel ports. It is useful on machines without network cards, or to install on laptops. In this section, we will discuss: Creating a parallel (laplink) cable. Connecting two computers with PLIP. Creating a Parallel Cable You can purchase a parallel cable at most computer supply stores. If you cannot do that, or you just want to know how it is done, the following table shows how to make one out of a normal parallel printer cable. Wiring a parallel cable for networking A-name A-End B-End Descr. Post/Bit DATA0 -ERROR 2 15 15 2 Data 0/0x01 1/0x08 DATA1 +SLCT 3 13 13 3 Data 0/0x02 1/0x10 DATA2 +PE 4 12 12 4 Data 0/0x04 1/0x20 DATA3 -ACK 5 10 10 5 Strobe 0/0x08 1/0x40 DATA4 BUSY 6 11 11 6 Data 0/0x10 1/0x80 GND 18-25 18-25 GND -
Setting up PLIP Get a laplink cable. Confirm that both computers have a kernel with &man.lpt.4; driver support. - &prompt.root; dmesg | grep lp + &prompt.root; grep lp /var/run/dmesg.boot lpt0 at 0x378-0x37f irq 7 on isa lpt0: Interrupt-driven lp0: TCP/IP capable interface Plug in the laplink cable into the parallel interface on both computers. Configure the network interface parameters for lp0 on both sites as root. For example, if you want connect the host host1 with host2: host1 <-----> host2 IP Address 10.0.0.1 10.0.0.2 Configure the interface on host1 by doing: &prompt.root; ifconfig lp0 10.0.0.1 10.0.0.2 Configure the interface on host2 by doing: &prompt.root; ifconfig lp0 10.0.0.2 10.0.0.1 You now should have a working connection. Please read the manual pages &man.lp.4; and &man.lpt.4; for more details. You should also add both hosts to /etc/hosts: 127.0.0.1 localhost.my.domain localhost 10.0.0.1 host1.my.domain host1 10.0.0.2 host2.my.domain To confirm the connection works, go to each host and ping the other. For example, on host1: &prompt.root; ifconfig lp0 lp0: flags=8851<UP,POINTOPOINT,RUNNING,SIMPLEX,MULTICAST> mtu 1500 inet 10.0.0.1 --> 10.0.0.2 netmask 0xff000000 &prompt.root; netstat -r Routing tables Internet: Destination Gateway Flags Refs Use Netif Expire host2 host1 UH 4 127592 lp0 &prompt.root; ping -c 4 host2 PING host2 (10.0.0.2): 56 data bytes 64 bytes from 10.0.0.2: icmp_seq=0 ttl=255 time=2.774 ms 64 bytes from 10.0.0.2: icmp_seq=1 ttl=255 time=2.530 ms 64 bytes from 10.0.0.2: icmp_seq=2 ttl=255 time=2.556 ms 64 bytes from 10.0.0.2: icmp_seq=3 ttl=255 time=2.714 ms --- host2 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max/stddev = 2.530/2.643/2.774/0.103 ms
Aaron Kaplan Originally Written by Tom Rhodes Restructured and Added by IPv6 IPv6 (also know as IPng IP next generation) is the new version of the well known IP protocol (also know as IPv4). Like the other current *BSD systems, FreeBSD includes the KAME IPv6 reference implementation. So your FreeBSD system comes with all you will need to experiment with IPv6. This section focuses on getting IPv6 configured and running. In the early 1990s, people became aware of the rapidly diminishing address space of IPv4. Given the expansion rate of the Internet there were two major concerns: Running out of addresses. Today this is not so much of a concern anymore since private address spaces (10.0.0.0/8, 192.168.0.0/24, etc.) and Network Address Translation (NAT) are being employed. Router table entries were getting too large. This is still a concern today. IPv6 deals with these and many other issues: 128 bit address space. In other words theoretically there are 340,282,366,920,938,463,463,374,607,431,768,211,456 addresses available. This means there are approximately 6.67 * 10^27 IPv6 addresses per square meter on our planet. Routers will only store network aggregation addresses in their routing tables thus reducing the average space of a routing table to 8192 entries. There are also lots of other useful features of IPv6 such as: Address autoconfiguration (RFC2462) Anycast addresses (one-out-of many) Mandatory multicast addresses IPsec (IP security) Simplified header structure Mobile IP IPv4-to-IPv6 transition mechanisms For more information see: IPv6 overview at Sun.com IPv6.org KAME.net 6bone.net Background on IPv6 Addresses There are different types of IPv6 addresses: Unicast, Anycast and Multicast. Unicast addresses are the well known addresses. A packet sent to a unicast address arrives exactly at the interface belonging to the address. Anycast addresses are syntactically indistinguishable from unicast addresses but they address a group of interfaces. The packet destined for an anycast address will arrive at the nearest (in router metric) interface. Anycast addresses may only be used by routers. Multicast addresses identify a group of interfaces. A packet destined for a multicast address will arrive at all interfaces belonging to the multicast group. The IPv4 broadcast address (usually xxx.xxx.xxx.255) is expressed by multicast addresses in IPv6. Reserved IPv6 addresses: ipv6-address prefixlength(Bits) description Notes :: 128 Bits unspecified cf. 0.0.0.0 in IPv4 address ::1 128 Bits loopback address cf. 127.0.0.1 in IPv4 ::00:xx:xx:xx:xx 96 Bits embedded IPv4 The lower 32 bits are the address IPv4 address. Also called IPv4 compatible IPv6 address ::ff:xx:xx:xx:xx 96 Bits IPv4 mapped The lower 32 bits are the IPv6 address IPv4 address. For hosts which do not support IPv6 fe80:: - feb:: 10 Bits link-local cf. loopback address in IPv4 fec0:: - fef:: 10 Bits site-local ff:: 8 Bits multicast 001 (base 2) 3 Bits global unicast All global unicast addresses are assigned from this pool. The first 3 Bits are 001. Reading IPv6 Addresses The canonical form is represented as: x:x:x:x:x:x:x:x, each x being a 16 Bit hex value. For example FEBC:A574:382B:23C1:AA49:4592:4EFE:9982 Often an address will have long substrings of all zeros therefore each such substring can be abbreviated by ::. For example fe80::1 corresponds to the canonical form fe80:0000:0000:0000:0000:0000:0000:0001 A third form is to write the last 32 Bit part in the well known (decimal) IPv4 style with dots . as separators. For example 2002::10.0.0.1 corresponds to the (hexadecimal) canonical representation 2002:0000:0000:0000:0000:0000:000a:0001 which in turn is equivalent to writing 2002::a:1 By now the reader should be able to understand the following: &prompt.root; ifconfig rl0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500 inet 10.0.0.10 netmask 0xffffff00 broadcast 10.0.0.255 inet6 fe80::200:21ff:fe03:8e1%rl0 prefixlen 64 scopeid 0x1 ether 00:00:21:03:08:e1 media: Ethernet autoselect (100baseTX ) status: active fe80::200:21ff:fe03:8e1%rl0 is an auto configured link-local address. It includes the enscrambled Ethernet MAC as part of the auto configuration. For further information on the structure of IPv6 addresses see RFC2373. Getting Connected Currently there are four ways to connect to other IPv6 hosts and networks: Join the experimental 6bone Getting an IPv6 network from your upstream provider. Talk to your Internet provider for instructions. Tunnel via 6-to-4 Use the freenet6 port if you are on a dial-up connection. Here we will talk on how to connect to the 6bone since it currently seems to be the most popular way. First take a look at the 6bone site and find a 6bone connection nearest to you. Write to the responsible person and with a little bit of luck you will be given instructions on how to set up your connection. Usually this involves setting up a GRE (gif) tunnel. Here is a typical example on setting up a &man.gif.4; tunnel: &prompt.root; ifconfig gif0 create &prompt.root; ifconfig gif0 gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280 &prompt.root; ifconfig gif0 tunnel MY_IPv4_ADDR HIS_IPv4_ADDR &prompt.root; ifconfig gif0 inet6 alias MY_ASSIGNED_IPv6_TUNNEL_ENDPOINT_ADDR Replace the capitalized words by the information you received from the upstream 6bone node. This establishes the tunnel. Check if the tunnel is working by &man.ping6.8; 'ing ff02::1%gif0. You should receive two ping replies. In case you are intrigued by the address ff02:1%gif0, this is a multicast address. %gif0 states that the multicast address at network interface gif0 is to be used. Since we ping a multicast address the other endpoint of the tunnel should reply as well). By now setting up a route to your 6bone uplink should be rather straightforward: &prompt.root; route add -inet6 default -interface gif0 &prompt.root; ping6 -n MY_UPLINK &prompt.root; traceroute6 www.jp.freebsd.org (3ffe:505:2008:1:2a0:24ff:fe57:e561) from 3ffe:8060:100::40:2, 30 hops max, 12 byte packets 1 atnet-meta6 14.147 ms 15.499 ms 24.319 ms 2 6bone-gw2-ATNET-NT.ipv6.tilab.com 103.408 ms 95.072 ms * 3 3ffe:1831:0:ffff::4 138.645 ms 134.437 ms 144.257 ms 4 3ffe:1810:0:6:290:27ff:fe79:7677 282.975 ms 278.666 ms 292.811 ms 5 3ffe:1800:0:ff00::4 400.131 ms 396.324 ms 394.769 ms 6 3ffe:1800:0:3:290:27ff:fe14:cdee 394.712 ms 397.19 ms 394.102 ms This output will differ from machine to machine. By now you should be able to reach the IPv6 site www.kame.net and see the dancing tortoise - that is if you have a IPv6 enabled browser such as mozilla. DNS in the IPv6 World There are two new types of DNS records for IPv6: AAAA records, A6 records Using AAAA records is straightforward. Assign your hostname to the new IPv6 address you just got by adding: MYHOSTNAME AAAA MYIPv6ADDR To your primary zone DNS file. In case you do not serve your own DNS zones ask your DNS provider. Current versions of bind (version 8.3 and 9) support AAAA records.
diff --git a/en_US.ISO8859-1/books/handbook/kernelconfig/chapter.sgml b/en_US.ISO8859-1/books/handbook/kernelconfig/chapter.sgml index e1de7fdc0c..29a04edaf3 100644 --- a/en_US.ISO8859-1/books/handbook/kernelconfig/chapter.sgml +++ b/en_US.ISO8859-1/books/handbook/kernelconfig/chapter.sgml @@ -1,1484 +1,1484 @@ Jim Mock Updated and restructured by Jake Hamby Originally contributed by Configuring the FreeBSD Kernel Synopsis kernel building a custom kernel The kernel is the core of the FreeBSD operating system. It is responsible for managing memory, enforcing security controls, networking, disk access, and much more. While more and more of FreeBSD becomes dynamically configurable it is still occasionally necessary to reconfigure and recompile your kernel. After reading this chapter, you will know: Why you might need to build a custom kernel. How to write a kernel configuration file, or alter an existing configuration file. How to use the kernel configuration file to create and build a new kernel. How to install the new kernel. How to create any entries in /dev that may be required. How to troubleshoot if things go wrong. Why Build a Custom Kernel? Traditionally, FreeBSD has had what is called a monolithic kernel. This means that the kernel was one large program, supported a fixed list of devices, and if you wanted to change the kernel's behavior then you had to compile a new kernel, and then reboot your computer with the new kernel. Today, FreeBSD is rapidly moving to a model where much of the kernel's functionality is contained in modules which can be dynamically loaded and unloaded from the kernel as necessary. This allows the kernel to adapt to new hardware suddenly becoming available (such as PCMCIA cards in a laptop), or for new functionality to be brought into the kernel that was not necessary when the kernel was originally compiled. Colloquially these are called KLDs. Despite this, it is still necessary to carry out some static kernel configuration. In some cases this is because the functionality is so tied to the kernel that it can not be made dynamically loadable. In others it may simply be because no one has yet taken the time to write a dynamic loadable kernel module for that functionality yet. Building a custom kernel is one of the most important rites of passage nearly every Unix user must endure. This process, while time consuming, will provide many benefits to your FreeBSD system. Unlike the GENERIC kernel, which must support a wide range of hardware, a custom kernel only contains support for your PC's hardware. This has a number of benefits, such as: Faster boot time. Since the kernel will only probe the hardware you have on your system, the time it takes your system to boot will decrease dramatically. Less memory usage. A custom kernel often uses less memory than the GENERIC kernel, which is important because the kernel must always be present in real memory. For this reason, a custom kernel is especially useful on a system with a small amount of RAM. Additional hardware support. A custom kernel allows you to add in support for devices such as sound cards, which are not present in the GENERIC kernel. Building and Installing a Custom Kernel kernel building / installing First, let us take a quick tour of the kernel build directory. All directories mentioned will be relative to the main /usr/src/sys directory, which is also accessible through /sys. There are a number of subdirectories here representing different parts of the kernel, but the most important, for our purposes, are arch/conf, where you will edit your custom kernel configuration, and compile, which is the staging area where your kernel will be built. arch represents either i386, alpha, or pc98 (an alternative development branch of PC hardware, popular in Japan). Everything inside a particular architecture's directory deals with that architecture only; the rest of the code is common to all platforms to which FreeBSD could potentially be ported. Notice the logical organization of the directory structure, with each supported device, filesystem, and option in its own subdirectory. If there is not a /usr/src/sys directory on your system, then the kernel source has not been installed. The easiest way to do this is by running /stand/sysinstall as root, choosing Configure, then Distributions, then src, then sys. If you have an aversion to sysinstall and you have access to an official FreeBSD CDROM, then you can also install the source from the command line: &prompt.root; mount /cdrom &prompt.root; mkdir -p /usr/src/sys &prompt.root; ln -s /usr/src/sys /sys &prompt.root; cat /cdrom/src/ssys.[a-d]* | tar -xzvf - Next, move to the arch/conf directory and copy the GENERIC configuration file to the name you want to give your kernel. For example: &prompt.root; cd /usr/src/sys/i386/conf &prompt.root; cp GENERIC MYKERNEL Traditionally, this name is in all capital letters and, if you are maintaining multiple FreeBSD machines with different hardware, it is a good idea to name it after your machine's hostname. We will call it MYKERNEL for the purpose of this example. Storing your kernel config file directly under /usr/src can be a bad idea. If you are experiencing problems it can be tempting to just delete /usr/src and start again. Five seconds after you do that you realize that you have deleted your custom kernel config file. You might want to keep your kernel config file elsewhere, and then create a symbolic link to the file in the i386 directory. For example: &prompt.root; cd /usr/src/sys/i386/conf &prompt.root; mkdir /root/kernels &prompt.root; cp GENERIC /root/kernels/MYKERNEL &prompt.root; ln -s /root/kernels/MYKERNEL You must execute these and all of the following commands under the root account or you will get permission denied errors. Now, edit MYKERNEL with your favorite text editor. If you are just starting out, the only editor available will probably be vi, which is too complex to explain here, but is covered well in many books in the bibliography. However, FreeBSD does offer an easier editor called ee which, if you are a beginner, should be your editor of choice. Feel free to change the comment lines at the top to reflect your configuration or the changes you have made to differentiate it from GENERIC. SunOS If you have built a kernel under SunOS or some other BSD operating system, much of this file will be very familiar to you. If you are coming from some other operating system such as DOS, on the other hand, the GENERIC configuration file might seem overwhelming to you, so follow the descriptions in the Configuration File section slowly and carefully. Be sure to always check the file /usr/src/UPDATING, before you perform any update steps, in the case you sync your source tree with the latest sources of the FreeBSD project. In this file all important issues with updating FreeBSD are written down. /usr/src/UPDATING always fits to your version of the FreeBSD source, and is therefore more accurate for those information than the handbook. You must now compile the source code for the kernel. There are two procedures you can use to do this, and the one you will use depends on why you are rebuilding the kernel, and the version of FreeBSD you are running. If you have installed only the kernel source code, use procedure 1. If you are running a FreeBSD version prior to 4.0, and you are not upgrading to FreeBSD 4.0 or higher using the make world procedure, use procedure 1. If you are building a new kernel without updating the source code (perhaps just to add a new option, such as IPFIREWALL) you can use either procedure. If you are rebuilding the kernel as part of a make world process, use procedure 2. Procedure 1. Building a kernel the <quote>traditional</quote> way Run &man.config.8; to generate the kernel source code. &prompt.root; /usr/sbin/config MYKERNEL Change into the build directory. &prompt.root; cd ../../compile/MYKERNEL Compile the kernel. &prompt.root; make depend &prompt.root; make Install the new kernel. &prompt.root; make install Procedure 2. Building a kernel the <quote>new</quote> way Change to the /usr/src directory. &prompt.root; cd /usr/src Compile the kernel. &prompt.root; make buildkernel KERNCONF=MYKERNEL Install the new kernel. &prompt.root; make installkernel KERNCONF=MYKERNEL In FreeBSD 4.2 and older you must replace KERNCONF= with KERNEL=. 4.2-STABLE that was fetched before Feb 2nd, 2001 does not recognize KERNCONF=. cvsup anonymous CVS CTM CVS anonymous If you have not upgraded your source tree in any way (you have not run CVSup, CTM, or used anoncvs), then you should use the config, make depend, make, make install sequence. kernel.old The new kernel will be copied to the root directory as /kernel and the old kernel will be moved to /kernel.old. Now, shutdown the system and reboot to use your new kernel. In case something goes wrong, there are some troubleshooting instructions at the end of this chapter. Be sure to read the section which explains how to recover in case your new kernel does not boot. As of FreeBSD 5.0, kernels are installed along with their modules in /boot/kernel, and old kernels will be backed up as /boot/kernel.old. Other files relating to the boot process, such as the boot &man.loader.8; and configuration are also stored in /boot. Third party or custom modules may be placed in /boot/modules, although users should be aware that keeping modules in sync with the compiled kernel is very important. Modules not intended to run with the compiled kernel may result in instability or incorrectness. If you have added any new devices (such as sound cards) and you are running FreeBSD 4.X or previous versions, you may have to add some device nodes to your /dev directory before you can use them. For more information, take a look at Making Device Nodes section later on in this chapter. The Configuration File kernel LINT LINT kernel config file The general format of a configuration file is quite simple. Each line contains a keyword and one or more arguments. For simplicity, most lines only contain one argument. Anything following a # is considered a comment and ignored. The following sections describe each keyword, generally in the order they are listed in GENERIC, although some related keywords have been grouped together in a single section (such as Networking) even though they are actually scattered throughout the GENERIC file. An exhaustive list of options and more detailed explanations of the device lines is present in the LINT configuration file, located in the same directory as GENERIC. If you are in doubt as to the purpose or necessity of a line, check first in LINT. Quoting numbers In all versions of FreeBSD up to and including 3.X, &man.config.8; required that any strings in the configuration file that contained numbers used as text had to be enclosed in double quotes. This requirement was removed in the 4.X branch, which this book covers, so if you are on a pre-4.X system, see the /usr/src/sys/i386/conf/LINT and /usr/src/sys/i386/conf/GENERIC files on your system for examples. kernel example config file The following is an example GENERIC kernel configuration file with various additional comments where needed for clarity. This example should match your copy in /usr/src/sys/i386/conf/GENERIC fairly closely. For details of all the possible kernel options, see /usr/src/sys/i386/conf/LINT. # # GENERIC -- Generic kernel configuration file for FreeBSD/i386 # # For more information on this file, please read the handbook section on # Kernel Configuration Files: # # http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the # FreeBSD World Wide Web server (http://www.FreeBSD.ORG/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the # device lines is also present in the ./LINT configuration file. If you are # in doubt as to the purpose or necessity of a line, check first in LINT. # # $FreeBSD: src/sys/i386/conf/GENERIC,v 1.246 2000/03/09 16:32:55 jlemon Exp $ The following are the mandatory keywords required in every kernel you build: kernel options machine machine i386 This is the machine architecture. It must be either i386, alpha, or pc98. kernel options cpu cpu I386_CPU cpu I486_CPU cpu I586_CPU cpu I686_CPU The above specifies the type of CPU you have in your system. You may have multiple instances of the CPU line (i.e., you are not sure whether you should use I586_CPU or I686_CPU), however, for a custom kernel, it is best to specify only the CPU you have. If you are unsure of your - CPU type, you can use the &man.dmesg.8; command to view your boot + CPU type, you can check the /var/run/dmesg.boot file to view your boot up messages. In FreeBSD 5.0, support for I386_CPU is disabled by default. kernel options cpu type The Alpha architecture has different values for cpu. They include: cpu EV4 cpu EV5 If you are using an Alpha machine, you should be using one of the above CPU types. kernel options ident ident GENERIC This is the identification of the kernel. You should change this to whatever you named your kernel, as in our previous example, MYKERNEL. The value you put in the ident string will print when you boot up the kernel, so it is useful to give the new kernel a different name if you want to keep it separate from your usual kernel (i.e., you want to build an experimental kernel). kernel options maxusers maxusers n The maxusers option sets the size of a number of important system tables. This number is supposed to be roughly equal to the number of simultaneous users you expect to have on your machine. Starting with FreeBSD 4.5, the system will auto-tune this setting for you if you explicitly set it to 0 The auto-tuning algorithm sets maxuser equal to the amount of memory in the system, with a minimum of 32, and a maximum of 384.. If you are using an earlier version of FreeBSD, or you want to manage it yourself you will want to set maxusers to at least 4, especially if you are using the X Window System or compiling software. The reason is that the most important table set by maxusers is the maximum number of processes, which is set to 20 + 16 * maxusers, so if you set maxusers to 1, then you can only have 36 simultaneous processes, including the 18 or so that the system starts up at boot time, and the 15 or so you will probably create when you start the X Window System. Even a simple task like reading a manual page will start up nine processes to filter, decompress, and view it. Setting maxusers to 64 will allow you to have up to 1044 simultaneous processes, which should be enough for nearly all uses. If, however, you see the dreaded proc table full error when trying to start another program, or are running a server with a large number of simultaneous users (like ftp.FreeBSD.org), you can always increase the number and rebuild. maxusers does not limit the number of users which can log into your machine. It simply sets various table sizes to reasonable values considering the maximum number of users you will likely have on your system and how many processes each of them will be running. One keyword which does limit the number of simultaneous remote logins is pseudo-device pty 16. # Floating point support - do not disable. device npx0 at nexus? port IO_NPX irq 13 npx0 is the interface to the floating point math unit in FreeBSD, which is either the hardware co-processor or the software math emulator. This is not optional. # Pseudo devices - the number indicates how many units to allocate. pseudo-device loop # Network loopback This is the generic loopback device for TCP/IP. If you telnet or FTP to localhost (a.k.a., 127.0.0.1) it will come back at you through this pseudo-device. This is mandatory. Everything that follows is more or less optional. See the notes underneath or next to each option for more information. #makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols options MATH_EMULATE #Support for x87 emulation This line allows the kernel to simulate a math co-processor if your computer does not have one (386 or 486SX). If you have a 486DX, or a 386 or 486SX (with a separate 387 or 487 chip), or higher (Pentium, Pentium II, etc.), you can comment this line out. The normal math co-processor emulation routines that come with FreeBSD are not very accurate. If you do not have a math co-processor, and you need the best accuracy, it is recommended that you change this option to GPL_MATH_EMULATE to use the GNU math support, which is not included by default for licensing reasons. In FreeBSD 5.0, math emulation is disabled by default, as older CPUs that do not have native floating point math support are far less common, and in many cases not supported by the native FreeBSD kernel without other additional options. options INET #InterNETworking Networking support. Leave this in, even if you do not plan to be connected to a network. Most programs require at least loopback networking (i.e., making network connections within your PC), so this is essentially mandatory. options INET6 #IPv6 communications protocols This enables the IPv6 communication protocols. options FFS #Berkeley Fast Filesystem options FFS_ROOT #FFS usable as root device [keep this!] This is the basic hard drive filesystem. Leave it in if you boot from the hard disk. In FreeBSD 5.0, FFS_ROOT is no longer required. options UFS_ACL #Support for access control lists This option, present only in FreeBSD 5.0, enables kernel support for access control lists. This relies on the use of extended attributes and UFS2, and the feature is described in detail in the . ACLs are enabled by default, and should not be disabled in the kernel if they have been used previously on a file system, as this will remove the access control lists changing the way files are protected in unpredictable ways. options UFS_DIRHASH #Improve performance on big directories This option includes some code to speed up disk operations on large directories, at the expense of using a some additional memory. You would normally keep this for a large server, or interactive workstation, and remove it if you are using FreeBSD on a smaller system where memory is at a premium and disk access speed is less important, such as a firewall. options SOFTUPDATES #Enable FFS Soft Updates support This option enables Soft Updates in the kernel, this will help speed up write access on the disks. They are enabled by default in the 4.X branch but may not be turned on. Review the output from &man.mount.8; to see if you have them enabled. If you do not see the soft-updates option then you will need to activate it using the &man.tunefs.8; or &man.newfs.8; for new filesystems. options MFS #Memory Filesystem options MD_ROOT #MD is a potential root device This is the memory-mapped filesystem. This is basically a RAM disk for fast storage of temporary files, useful if you have a lot of swap space that you want to take advantage of. A perfect place to mount an MFS partition is on the /tmp directory, since many programs store temporary data here. To mount an MFS RAM disk on /tmp, add the following line to /etc/fstab: /dev/ad1s2b /tmp mfs rw 0 0 Now you simply need to either reboot, or run the command mount /tmp. In FreeBSD 5.0, &man.md.4;-backed UFS file systems are used for memory file systems rather than MFS. Information on configuring MD-backed file systems may be found in the man pages for &man.mdconfig.8; and &man.mdmfs.8;. As a result, the MFS option is no longer supported. kernel options NFS kernel options NFS_ROOT options NFS #Network Filesystem options NFS_ROOT #NFS usable as root device, NFS required The network filesystem. Unless you plan to mount partitions from a Unix file server over TCP/IP, you can comment these out. kernel options MSDOSFS options MSDOSFS #MSDOS Filesystem The MS-DOS filesystem. Unless you plan to mount a DOS formatted hard drive partition at boot time, you can safely comment this out. It will be automatically loaded the first time you mount a DOS partition, as described above. Also, the excellent mtools software (in the ports collection) allows you to access DOS floppies without having to mount and unmount them (and does not require MSDOSFS at all). options CD9660 #ISO 9660 Filesystem options CD9660_ROOT #CD-ROM usable as root, CD9660 required The ISO 9660 filesystem for CDROMs. Comment it out if you do not have a CDROM drive or only mount data CDs occasionally (since it will be dynamically loaded the first time you mount a data CD). Audio CDs do not need this filesystem. options PROCFS #Process filesystem The process filesystem. This is a pretend filesystem mounted on /proc which allows programs like &man.ps.1; to give you more information on what processes are running. In FreeBSD 5.0, use of PROCFS is not required under most circumstances, as most debugging and monitoring tools have been adapted to run without PROCFS. In addition, 5.0-CURRENT kernels making use of PROCFS must now also include support for PSEUDOFS: options PSEUDOFS #Pseudo-filesystem framework PSEUDOFS is not available in FreeBSD 4.X. Unlike in FreeBSD 4.X, new installs of FreeBSD 5.0 will not mount the process file system by default. options COMPAT_43 #Compatible with BSD 4.3 [KEEP THIS!] Compatibility with 4.3BSD. Leave this in; some programs will act strangely if you comment this out. options COMPAT_FREEBSD4 #Compatible with FreeBSD4 This option is required on FreeBSD 5.0 i386 and alpha systems to support applications compiled on older versions of FreeBSD that use older system call interfaces. It is recommended that this option be used on all i386 and alpha systems that may run older applications; platforms that gained support only in 5.0, such as ia64 and sparc64, do not require this option. options SCSI_DELAY=15000 #Delay (in ms) before probing SCSI This causes the kernel to pause for 15 seconds before probing each SCSI device in your system. If you only have IDE hard drives, you can ignore this, otherwise you will probably want to lower this number, perhaps to 5 seconds, to speed up booting. Of course, if you do this, and FreeBSD has trouble recognizing your SCSI devices, you will have to raise it back up. options UCONSOLE #Allow users to grab the console Allow users to grab the console, which is useful for X users. For example, you can create a console xterm by typing xterm -C, which will display any &man.write.1;, &man.talk.1;, and any other messages you receive, as well as any console messages sent by the kernel. In FreeBSD 5.0, UCONSOLE is no longer required. options USERCONFIG #boot -c editor This option allows you to boot the configuration editor from the boot menu. options VISUAL_USERCONFIG #visual boot -c editor This option allows you to boot the visual configuration editor from the boot menu. From FreeBSD versions 5.0 and later, userconfig has been depreciated in favor of the new &man.device.hints.5; method. For more information on &man.device.hints.5; please visit options KTRACE #ktrace(1) support This enables kernel process tracing, which is useful in debugging. options SYSVSHM #SYSV-style shared memory This option provides for System V shared memory. The most common use of this is the XSHM extension in X, which many graphics-intensive programs will automatically take advantage of for extra speed. If you use X, you will definitely want to include this. options SYSVSEM #SYSV-style semaphores Support for System V semaphores. Less commonly used but only adds a few hundred bytes to the kernel. options SYSVMSG #SYSV-style message queues Support for System V messages. Again, only adds a few hundred bytes to the kernel. The &man.ipcs.1; command will list any processes using each of these System V facilities. options P1003_1B #Posix P1003_1B real-time extensions options _KPOSIX_PRIORITY_SCHEDULING Real-time extensions added in the 1993 POSIX. Certain applications in the ports collection use these (such as StarOffice). In FreeBSD 5.0, all of this functionality is now provided by the _KPOSIX_PRIORITY_SCHEDULING option, and P1003_1B is no longer required. kernel options ICMP_BANDLIM Denial of Service (DoS) options ICMP_BANDLIM #Rate limit bad replies This option enables ICMP error response bandwidth limiting. You typically want this option as it will help protect the machine from denial of service packet attacks. In FreeBSD 5.0, this feature is enabled by default and the ICMP_BANDLIM option is not required. kernel options SMP # To make an SMP kernel, the next two are needed #options SMP # Symmetric MultiProcessor Kernel #options APIC_IO # Symmetric (APIC) I/O The above are both required for SMP support. device isa All PCs supported by FreeBSD have one of these. If you have an IBM PS/2 (Micro Channel Architecture), FreeBSD provides some limited support at this time. For more information about the MCA support, see /usr/src/sys/i386/conf/LINT. device eisa Include this if you have an EISA motherboard. This enables auto-detection and configuration support for all devices on the EISA bus. device pci Include this if you have a PCI motherboard. This enables auto-detection of PCI cards and gatewaying from the PCI to ISA bus. # Floppy drives device fdc0 at isa? port IO_FD1 irq 6 drq 2 device fd0 at fdc0 drive 0 device fd1 at fdc0 drive 1 This is the floppy drive controller. fd0 is the A: floppy drive, and fd1 is the B: drive. device ata This driver supports all ATA and ATAPI devices. You only need one device ata line for the kernel to detect all PCI ATA/ATAPI devices on modern machines. device atadisk # ATA disk drives This is needed along with device ata for ATA disk drives. device atapicd # ATAPI CDROM drives This is needed along with device ata for ATAPI CDROM drives. device atapifd # ATAPI floppy drives This is needed along with device ata for ATAPI floppy drives. device atapist # ATAPI tape drives This is needed along with device ata for ATAPI tape drives. options ATA_STATIC_ID #Static device numbering This makes the controller number static (like the old driver) or else the device numbers are dynamically allocated. # ATA and ATAPI devices device ata0 at isa? port IO_WD1 irq 14 device ata1 at isa? port IO_WD2 irq 15 Use the above for older, non-PCI systems. # SCSI Controllers device ahb # EISA AHA1742 family device ahc # AHA2940 and onboard AIC7xxx devices device amd # AMD 53C974 (Teckram DC-390(T)) device dpt # DPT Smartcache - See LINT for options! device isp # Qlogic family device ncr # NCR/Symbios Logic device sym # NCR/Symbios Logic (newer chipsets) device adv0 at isa? device adw device bt0 at isa? device aha0 at isa? device aic0 at isa? SCSI controllers. Comment out any you do not have in your system. If you have an IDE only system, you can remove these altogether. # SCSI peripherals device scbus # SCSI bus (required) device da # Direct Access (disks) device sa # Sequential Access (tape etc) device cd # CD device pass # Passthrough device (direct SCSI access) SCSI peripherals. Again, comment out any you do not have, or if you have only IDE hardware, you can remove them completely. # RAID controllers device ida # Compaq Smart RAID device amr # AMI MegaRAID device mlx # Mylex DAC960 family Supported RAID controllers. If you do not have any of these, you can comment them out or remove them. # atkbdc0 controls both the keyboard and the PS/2 mouse device atkbdc0 at isa? port IO_KBD The keyboard controller (atkbdc) provides I/O services for the AT keyboard and PS/2 style pointing devices. This controller is required by the keyboard driver (atkbd) and the PS/2 pointing device driver (psm). device atkbd0 at atkbdc? irq 1 The atkbd driver, together with atkbdc controller, provides access to the AT 84 keyboard or the AT enhanced keyboard which is connected to the AT keyboard controller. device psm0 at atkbdc? irq 12 Use this device if your mouse plugs into the PS/2 mouse port. device vga0 at isa? The video card driver. # splash screen/screen saver pseudo-device splash Splash screen at start up! Screen savers require this too. # syscons is the default console driver, resembling an SCO console device sc0 at isa? sc0 is the default console driver, which resembles a SCO console. Since most full-screen programs access the console through a terminal database library like termcap, it should not matter whether you use this or vt0, the VT220 compatible console driver. When you log in, set your TERM variable to scoansi if full-screen programs have trouble running under this console. # Enable this and PCVT_FREEBSD for pcvt vt220 compatible console driver #device vt0 at isa? #options XSERVER # support for X server on a vt console #options FAT_CURSOR # start with block cursor # If you have a ThinkPAD, uncomment this along with the rest of the PCVT lines #options PCVT_SCANSET=2 # IBM keyboards are non-std This is a VT220-compatible console driver, backward compatible to VT100/102. It works well on some laptops which have hardware incompatibilities with sc0. Also set your TERM variable to vt100 or vt220 when you log in. This driver might also prove useful when connecting to a large number of different machines over the network, where termcap or terminfo entries for the sc0 device are often not available — vt100 should be available on virtually any platform. # Power management support (see LINT for more options) device apm0 at nexus? disable flags 0x20 # Advanced Power Management Advanced Power Management support. Useful for laptops. # PCCARD (PCMCIA) support device card device pcic0 at isa? irq 10 port 0x3e0 iomem 0xd0000 device pcic1 at isa? irq 11 port 0x3e2 iomem 0xd4000 disable PCMCIA support. You want this if you are using a laptop. # Serial (COM) ports device sio0 at isa? port IO_COM1 flags 0x10 irq 4 device sio1 at isa? port IO_COM2 irq 3 device sio2 at isa? disable port IO_COM3 irq 5 device sio3 at isa? disable port IO_COM4 irq 9 These are the four serial ports referred to as COM1 through COM4 in the MS-DOS/Windows world. If you have an internal modem on COM4 and a serial port at COM2, you will have to change the IRQ of the modem to 2 (for obscure technical reasons, IRQ2 = IRQ 9) in order to access it from FreeBSD. If you have a multiport serial card, check the manual page for &man.sio.4; for more information on the proper values for these lines. Some video cards (notably those based on S3 chips) use IO addresses in the form of 0x*2e8, and since many cheap serial cards do not fully decode the 16-bit IO address space, they clash with these cards making the COM4 port practically unavailable. Each serial port is required to have a unique IRQ (unless you are using one of the multiport cards where shared interrupts are supported), so the default IRQs for COM3 and COM4 cannot be used. # Parallel port device ppc0 at isa? irq 7 This is the ISA-bus parallel port interface. device ppbus # Parallel port bus (required) Provides support for the parallel port bus. device lpt # Printer Support for parallel port printers. All three of the above are required to enable parallel printer support. device plip # TCP/IP over parallel This is the driver for the parallel network interface. device ppi # Parallel port interface device The general-purpose I/O (geek port) + IEEE1284 I/O. #device vpo # Requires scbus and da zip drive This is for an Iomega Zip drive. It requires scbus and da support. Best performance is achieved with ports in EPP 1.9 mode. # PCI Ethernet NICs. device de # DEC/Intel DC21x4x (Tulip) device fxp # Intel EtherExpress PRO/100B (82557, 82558) device tx # SMC 9432TX (83c170 EPIC) device vx # 3Com 3c590, 3c595 (Vortex) device wx # Intel Gigabit Ethernet Card (Wiseman) Various PCI network card drivers. Comment out or remove any of these not present in your system. # PCI Ethernet NICs that use the common MII bus controller code. device miibus # MII bus support MII bus support is required for some PCI 10/100 Ethernet NICs, namely those which use MII-compliant transceivers or implement transceiver control interfaces that operate like an MII. Adding device miibus to the kernel config pulls in support for the generic miibus API and all of the PHY drivers, including a generic one for PHYs that are not specifically handled by an individual driver. device dc # DEC/Intel 21143 and various workalikes device rl # RealTek 8129/8139 device sf # Adaptec AIC-6915 (Starfire) device sis # Silicon Integrated Systems SiS 900/SiS 7016 device ste # Sundance ST201 (D-Link DFE-550TX) device tl # Texas Instruments ThunderLAN device vr # VIA Rhine, Rhine II device wb # Winbond W89C840F device xl # 3Com 3c90x (Boomerang, Cyclone) Drivers that use the MII bus controller code. # ISA Ethernet NICs. device ed0 at isa? port 0x280 irq 10 iomem 0xd8000 device ex device ep # WaveLAN/IEEE 802.11 wireless NICs. Note: the WaveLAN/IEEE really # exists only as a PCMCIA device, so there is no ISA attachment needed # and resources will always be dynamically assigned by the pccard code. device wi # Aironet 4500/4800 802.11 wireless NICs. Note: the declaration below will # work for PCMCIA and PCI cards, as well as ISA cards set to ISA PnP # mode (the factory default). If you set the switches on your ISA # card for a manually chosen I/O address and IRQ, you must specify # those parameters here. device an # The probe order of these is presently determined by i386/isa/isa_compat.c. device ie0 at isa? port 0x300 irq 10 iomem 0xd0000 device fe0 at isa? port 0x300 device le0 at isa? port 0x300 irq 5 iomem 0xd0000 device lnc0 at isa? port 0x280 irq 10 drq 0 device cs0 at isa? port 0x300 device sn0 at isa? port 0x300 irq 10 # requires PCCARD (PCMCIA) support to be activated #device xe0 at isa? ISA Ethernet drivers. See /usr/src/sys/i386/conf/LINT for which cards are supported by which driver. pseudo-device ether # Ethernet support ether is only needed if you have an Ethernet card. It includes generic Ethernet protocol code. pseudo-device sl 1 # Kernel SLIP sl is for SLIP support. This has been almost entirely supplanted by PPP, which is easier to set up, better suited for modem-to-modem connection, and more powerful. The number after sl specifies how many simultaneous SLIP sessions to support. pseudo-device ppp 1 # Kernel PPP This is for kernel PPP support for dial-up connections. There is also a version of PPP implemented as a userland application that uses tun and offers more flexibility and features such as demand dialing. The number after ppp specifies how many simultaneous PPP connections to support. pseudo-device tun # Packet tunnel. This is used by the userland PPP software. A number after tun specifies the number of simultaneous PPP sessions to support. See the PPP section of this book for more information. pseudo-device pty # Pseudo-ttys (telnet etc) This is a pseudo-terminal or simulated login port. It is used by incoming telnet and rlogin sessions, xterm, and some other applications such as Emacs. A number after pty indicates the number of ptys to create. If you need more than the default of 16 simultaneous xterm windows and/or remote logins, be sure to increase this number accordingly, up to a maximum of 256. pseudo-device md # Memory disks Memory disk pseudo-devices. pseudo-device gif or pseudo-device gif 4 # IPv6 and IPv4 tunneling This implements IPv6 over IPv4 tunneling, IPv4 over IPv6 tunneling, IPv4 over IPv4 tunneling, and IPv6 over IPv6 tunneling. Beginning with FreeBSD 4.4 the gif device is auto-cloning, and you should use the first example (without the number after gif). Earlier versions of FreeBSD require the number. pseudo-device faith 1 # IPv6-to-IPv4 relaying (translation) This pseudo-device captures packets that are sent to it and diverts them to the IPv4/IPv6 translation daemon. # The `bpf' pseudo-device enables the Berkeley Packet Filter. # Be aware of the administrative consequences of enabling this! pseudo-device bpf # Berkeley packet filter This is the Berkeley Packet Filter. This pseudo-device allows network interfaces to be placed in promiscuous mode, capturing every packet on a broadcast network (e.g., an Ethernet). These packets can be captured to disk and or examined with the &man.tcpdump.1; program. The bpf pseudo-device is also used by &man.dhclient.8; to obtain the IP address of the default router (gateway) and so on. If you use DHCP, leave this uncommented. # USB support #device uhci # UHCI PCI->USB interface #device ohci # OHCI PCI->USB interface #device usb # USB Bus (required) #device ugen # Generic #device uhid # Human Interface Devices #device ukbd # Keyboard #device ulpt # Printer #device umass # Disks/Mass storage - Requires scbus and da #device ums # Mouse # USB Ethernet, requires mii #device aue # ADMtek USB ethernet #device cue # CATC USB ethernet #device kue # Kawasaki LSI USB ethernet Support for various USB devices. For more information and additional devices supported by FreeBSD, see /usr/src/sys/i386/conf/LINT. Making Device Nodes device nodes MAKEDEV If you are running FreeBSD 5.0 or later you can safely skip this section. These versions use &man.devfs.5; to allocate device nodes transparently for the user. Almost every device in the kernel has a corresponding node entry in the /dev directory. These nodes look like regular files, but are actually special entries into the kernel which programs use to access the device. The shell script /dev/MAKEDEV, which is executed when you first install the operating system, creates nearly all of the device nodes supported. However, it does not create all of them, so when you add support for a new device, it pays to make sure that the appropriate entries are in this directory, and if not, add them. Here is a simple example: Suppose you add the IDE CD-ROM support to the kernel. The line to add is: device acd0 This means that you should look for some entries that start with acd0 in the /dev directory, possibly followed by a letter, such as c, or preceded by the letter r, which means a raw device. It turns out that those files are not there, so you must change to the /dev directory and type: MAKEDEV &prompt.root; sh MAKEDEV acd0 When this script finishes, you will find that there are now acd0c and racd0c entries in /dev so you know that it executed correctly. For sound cards, the following command creates the appropriate entries: &prompt.root; sh MAKEDEV snd0 When creating device nodes for devices such as sound cards, if other people have access to your machine, it may be desirable to protect the devices from outside access by adding them to the /etc/fbtab file. See &man.fbtab.5; for more information. Follow this simple procedure for any other non-GENERIC devices which do not have entries. All SCSI controllers use the same set of /dev entries, so you do not need to create these. Also, network cards and SLIP/PPP pseudo-devices do not have entries in /dev at all, so you do not have to worry about these either. If Something Goes Wrong There are five categories of trouble that can occur when building a custom kernel. They are: config fails: If the &man.config.8; command fails when you give it your kernel description, you have probably made a simple error somewhere. Fortunately, &man.config.8; will print the line number that it had trouble with, so you can quickly skip to it with vi. For example, if you see: config: line 17: syntax error You can skip to the problem in vi by typing 17G in command mode. Make sure the keyword is typed correctly, by comparing it to the GENERIC kernel or another reference. make fails: If the make command fails, it usually signals an error in your kernel description, but not severe enough for &man.config.8; to catch it. Again, look over your configuration, and if you still cannot resolve the problem, send mail to the &a.questions; with your kernel configuration, and it should be diagnosed very quickly. Installing the new kernel fails: If the kernel compiled fine, but failed to install (the make install or make installkernel command failed), the first thing to check is if your system is running at securelevel 1 or higher (see &man.init.8;). The kernel installation tries to remove the immutable flag from your kernel and set the immutable flag on the new one. Since securelevel 1 or higher prevents unsetting the immutable flag for any files on the system, the kernel installation needs to be performed at securelevel 0 or lower. The kernel does not boot: If your new kernel does not boot, or fails to recognize your devices, do not panic! Fortunately, FreeBSD has an excellent mechanism for recovering from incompatible kernels. Simply choose the kernel you want to boot from at the FreeBSD boot loader. You can access this when the system counts down from 10. Hit any key except for the Enter key, type unload and then type boot kernel.old, or the filename of any other kernel that will boot properly. When reconfiguring a kernel, it is always a good idea to keep a kernel that is known to work on hand. After booting with a good kernel you can check over your configuration file and try to build it again. One helpful resource is the /var/log/messages file which records, among other things, all of the kernel messages from every successful boot. Also, the &man.dmesg.8; command will print the kernel messages from the current boot. If you are having trouble building a kernel, make sure to keep a GENERIC, or some other kernel that is known to work on hand as a different name that will not get erased on the next build. You cannot rely on kernel.old because when installing a new kernel, kernel.old is overwritten with the last installed kernel which may be non-functional. Also, as soon as possible, move the working kernel to the proper kernel location or commands such as &man.ps.1; will not work properly. The proper command to unlock the kernel file that make installs (in order to move another kernel back permanently) is: &prompt.root; chflags noschg /kernel If you find you cannot do this, you are probably running at a &man.securelevel.8; greater than zero. Edit kern_securelevel in /etc/rc.conf and set it to -1, then reboot. You can change it back to its previous setting when you are happy with your new kernel. And, if you want to lock your new kernel into place, or any file for that matter, so that it cannot be moved or tampered with: &prompt.root; chflags schg /kernel In FreeBSD 5.0, kernels are not installed with the system immutable flag, so this is unlikely to be the source of the problem you're experiencing. The kernel works, but &man.ps.1; does not work any more: If you have installed a different version of the kernel from the one that the system utilities have been built with, for example, a 4.X kernel on a 3.X system, many system-status commands like &man.ps.1; and &man.vmstat.8; will not work any more. You must recompile the libkvm library as well as these utilities. This is one reason it is not normally a good idea to use a different version of the kernel from the rest of the operating system. diff --git a/en_US.ISO8859-1/books/handbook/multimedia/chapter.sgml b/en_US.ISO8859-1/books/handbook/multimedia/chapter.sgml index cde6c9f814..8e09d0b275 100644 --- a/en_US.ISO8859-1/books/handbook/multimedia/chapter.sgml +++ b/en_US.ISO8859-1/books/handbook/multimedia/chapter.sgml @@ -1,1415 +1,1415 @@ Ross Lippert Edited by Multimedia Synopsis FreeBSD supports a wide variety of sound cards, allowing you to enjoy high fidelity output from your computer. This includes the ability to record and playback audio in the MPEG Audio Layer 3 (MP3), WAV, and Ogg Vorbis formats as well as many other formats. The FreeBSD Ports Collection also contains applications allowing you to edit your recorded audio, add sound effects, and control attached MIDI devices. With some willingness to experiment, FreeBSD can support playback of video files and DVD's. The number of applications to encode, convert, and playback various video media is more limited than the number of sound applications. For example as of this writing, there is no good re-encoding application in the FreeBSD Ports Collection, which could be use to interconvert between formats, as there is with audio/sox. However, the software landscape in this area is changing rapidly. This chapter will describe the necessary steps to configure your sound card. The configuration and installation of XFree86 () has already taken care of the hardware issues for your video card, though there may be some tweaks to apply for better playback. After reading this chapter, you will know: How to configure your system so that your sound card is recognized. Methods to test that your card is working using sample applications. How to troubleshoot your sound setup. How to playback and encode MP3s and other audio. How video is supported by XFree86. Some video player/encoder ports which give good results. How to playback DVD's, .mpg and .avi files. How to rip CD and DVD information into files. Before reading this chapter, you should: Know how to configure and install a new kernel (). For the video sections, it is assumed that XFree86 4.X (x11/XFree86-4) has been installed. XFree86 3.X may work, but it has not been tested with what is described in this chapter. If you find that something described here does work with XFree86 3.X please let us know. Trying to mount an audio CD or a video DVD with the &man.mount.8; command will result in an error, at least, and a kernel panic, at worst. These media have specialized encodings which differ from the usual ISO-filesystem. Moses Moore Contributed by Setting Up The Sound Card Locating the Correct Device PCI ISA sound cards Before you begin, you should know the model of the card you have, the chip it uses, and whether it is a PCI or ISA card. FreeBSD supports a wide variety of both PCI and ISA cards. If you do not see your card in the following list, check the &man.pcm.4; manual page. This is not a complete list; however, it does list some of the most common cards. Crystal 4237, 4236, 4232, 4231 Yamaha OPL-SAx OPTi931 Ensoniq AudioPCI 1370/1371 ESS Solo-1/1E NeoMagic 256AV/ZX Sound Blaster Pro, 16, 32, AWE64, AWE128, Live Creative ViBRA16 Advanced Asound 100, 110, and Logic ALS120 ES 1868, 1869, 1879, 1888 Gravis UltraSound Aureal Vortex 1 or 2 kernel configuration To use your sound device, you will need to load the proper device driver. This may be accomplished in one of two ways. The easiest way is to simply load a kernel module for your sound card with &man.kldload.8;. Alternatively, you may statically compile in support for your sound card in your kernel. The sections below provide the information you need to add support for your hardware in this manner. For more information about recompiling your kernel, please see . Creative, Advance, and ESS Sound Cards If you have one of the above cards, you will need to add: device pcm to your kernel configuration file. If you have a PnP ISA card, you will also need to add: device sbc For a non-PnP ISA card, add: device pcm device sbc0 at isa? port 0x220 irq 5 drq 1 flags 0x15 to your kernel configuration file. The settings shown above are the defaults. You may need to change the IRQ or the other settings to match your card. See the &man.sbc.4; manual page for more information. The Sound Blaster Live is not supported under FreeBSD 4.0 without a patch, which this section will not cover. It is recommended that you update to the latest -STABLE before trying to use this card. Gravis UltraSound Cards For a PnP ISA card, you will need to add: device pcm device gusc to your kernel configuration file. If you have a non-PnP ISA card, you will need to add: device pcm device gus0 at isa? port 0x220 irq 5 drq 1 flags 0x13 to your kernel configuration file. You may need to change the IRQ or the other settings to match your card. See the &man.gusc.4; manual page for more information. Crystal Sound Cards For Crystal cards, you will need to add: device pcm device csa to your kernel configuration file. Generic Support For PnP ISA or PCI cards, you will need to add: device pcm to your kernel configuration file. If you have a non-PnP ISA sound card that does not have a bridge driver, you will need to add: device pcm0 at isa? irq 10 drq 1 flags 0x0 to your kernel configuration file. You may need to change the IRQ or the other settings to match your card. Onboard Sound Some systems with built-in motherboard sound devices may require the following option in your kernel configuration: options PNPBIOS Creating and Testing the Device Nodes device nodes - After you reboot, log in and run dmesg | grep - pcm as shown below: + After you reboot, log in and check for the device in the + /var/run/dmesg.boot file, as shown below: - &prompt.root; dmesg | grep pcm + &prompt.root; grep pcm /var/run/dmesg.boot pcm0: <SB16 DSP 4.11> on sbc0 The output from your system may look different. If no pcm devices show up, something went wrong earlier. If that happens, go through your kernel configuration file again and make sure you chose the correct device. Common problems are listed in . If you are running FreeBSD 5.0 or later, you can safely skip the rest of this section. These versions use &man.devfs.5; to automatically create devices nodes. If the previous command returned pcm0, you will have to run the following as root: &prompt.root; cd /dev &prompt.root; sh MAKEDEV snd0 If the command returned pcm1, follow the same steps as shown above, replacing snd0 with snd1. The above commands will not create a /dev/snd device! MAKEDEV will create a group of device nodes, including: Device Description /dev/audio SPARC-compatible audio device /dev/dsp Digitized voice device /dev/dspW Like /dev/dsp, but 16 bits per sample /dev/midi Raw midi access device /dev/mixer Control port mixer device /dev/music Level 2 sequencer interface /dev/sequencer Sequencer device /dev/pss Programmable device interface If all goes well, you should now have a functioning sound card. If your CD-ROM or DVD-ROM drive is properly coupled to your sound card, you can put a CD in the drive and play it with &man.cdcontrol.1;: &prompt.user; cdcontrol -f /dev/acd0c play 1 Various applications, such as audio/workman offer a better interface. You may want to install an application such as audio/mpg123 to listen to MP3 audio files. Common Problems Error Solution device node unsupported subdevice XX One or more of the device nodes was not created correctly. Repeat the steps above. I/O port sb_dspwr(XX) timed out The I/O port is not set correctly. IRQ bad irq XX The IRQ is set incorrectly. Make sure that the set IRQ and the sound IRQ are the same. xxx: gus pcm not attached, out of memory There is not enough available memory to use the device. DSP xxx: can't open /dev/dsp! Check with fstat | grep dsp if another application is holding the device open. Noteworthy troublemakers are esound and KDE's sound support. Munish Chopra Contributed by Utilizing Multiple Sound Sources It is often desirable to have multiple sources of sound that are able to play simultaneously, such as when esound or artsd do not support sharing of the sound device with a certain application. FreeBSD lets you do this through Virtual Sound Channels, which can be set with the &man.sysctl.8; facility. Virtual channels allow you to multiplex your sound card's playback channels by mixing sound in the kernel. To set the number of virtual channels, there are two sysctl knobs which, if you are the root user, can be set like this: &prompt.root; sysctl hw.snd.pcm0.vchans=4 &prompt.root; sysctl hw.snd.maxautovchans=4 The above example allocates four virtual channels, which is a practical number for everyday use. hw.snd.pcm0.vchans is the number of virtual channels pcm0 has, and is configurable once a device has been attached. hw.snd.maxautovchans is the number of virtual channels a new audio device is given when it is attached using &man.kldload.8;. Since the pcm module can be loaded independently of the hardware drivers, hw.snd.maxautovchans can store how many virtual channels any devices which are attached later will be given. If you are not using &man.devfs.5;, you will have to point your applications at /dev/dsp0.x, where x is 0 to 3 if hw.snd.pcm.0.vchans is set to 4 as in the above example. On a system using &man.devfs.5;, the above will automatically be allocated transparently to the user. Chern Lee Contributed by MP3 Audio MP3 (MPEG Layer 3 Audio) accomplishes near CD-quality sound, leaving no reason to let your FreeBSD workstation fall short of its offerings. MP3 Players By far, the most popular XFree86 MP3 player is XMMS (X Multimedia System). Winamp skins can be used with XMMS since the GUI is almost identical to that of Nullsoft's Winamp. XMMS also has native plug-in support. XMMS can be installed from the multimedia/xmms port or package. XMMS' interface is intuitive, with a playlist, graphic equalizer, and more. Those familiar with Winamp will find XMMS simple to use. The audio/mpg123 port is an alternative, command-line MP3 player. mpg123 can be run by specifying the sound device and the MP3 file on the command line, as shown below: &prompt.root; mpg123 -a /dev/dsp1.0 Foobar-GreatestHits.mp3 High Performance MPEG 1.0/2.0/2.5 Audio Player for Layer 1, 2 and 3. Version 0.59r (1999/Jun/15). Written and copyrights by Michael Hipp. Uses code from various people. See 'README' for more! THIS SOFTWARE COMES WITH ABSOLUTELY NO WARRANTY! USE AT YOUR OWN RISK! Playing MPEG stream from BT - Foobar-GreastHits.mp3 ... MPEG 1.0 layer III, 128 kbit/s, 44100 Hz joint-stereo /dev/dsp1.0 should be replaced with the dsp device entry on your system. Ripping CD Audio Tracks Before encoding a CD or CD track to MP3, the audio data on the CD must be ripped onto the hard drive. This is done by copying the raw CDDA (CD Digital Audio) data to WAV files. The cdda2wav tool, which is a part of the sysutils/cdrtools suite, is used for ripping audio information from CDs and the information associated with them. With the audio CD in the drive, the following command can be issued (as root) to rip an entire CD into individual (per track) WAV files: &prompt.root; cdda2wav -D 0,1,0 -B cdda2wav will support ATAPI (IDE) CDROM drives. To rip from an IDE drive, specify the device name in place of the SCSI unit numbers. For example, to rip track 7 from an IDE drive: &prompt.root; cdda2wav -D /dev/acd0a -t 7 The indicates the SCSI device 0,1,0, which corresponds to the output of cdrecord -scanbus. To rip individual tracks, make use of the option as shown: &prompt.root; cdda2wav -D 0,1,0 -t 7 This example rips track seven of the audio CDROM. To rip a range of tracks, for example, track one to seven, specify a range: &prompt.root; cdda2wav -D 0,1,0 -t 1+7 The utility &man.dd.1; can also be used to extract audio tracks on ATAPI drives, read for more information on that possibility. Encoding MP3s Nowadays, the mp3 encoder of choice is lame. Lame can be found at audio/lame in the ports tree. Using the ripped WAV files, the following command will convert audio01.wav to audio01.mp3: &prompt.root; lame -h -b 128 \ --tt "Foo Song Title" \ --ta "FooBar Artist" \ --tl "FooBar Album" \ --ty "2001" \ --tc "Ripped and encoded by Foo" \ --tg "Genre" \ audio01.wav audio01.mp3 128 kbits seems to be the standard MP3 bitrate in use. Many enjoy the higher quality 160, or 192. The higher the bitrate, the more disk space the resulting MP3 will consume--but the quality will be higher. The option turns on the higher quality but a little slower mode. The options beginning with indicate ID3 tags, which usually contain song information, to be embedded within the MP3 file. Additional encoding options can be found by consulting the lame man page. Decoding MP3s In order to burn an audio CD from MP3s, they must be converted to a non-compressed WAV format. Both XMMS and mpg123 support the output of MP3 to an uncompressed file format. Writing to Disk in XMMS: Launch XMMS. Right-click on the window to bring up the XMMS menu. Select Preference under Options. Change the Output Plugin to Disk Writer Plugin. Press Configure. Enter (or choose browse) a directory to write the uncompressed files to. Load the MP3 file into XMMS as usual, with volume at 100% and EQ settings turned off. Press PlayXMMS will appear as if it is playing the MP3, but no music will be heard. It is actually playing the MP3 to a file. Be sure to set the default Output Plugin back to what it was before in order to listen to MP3s again. Writing to stdout in mpg123: Run mpg123 -s audio01.mp3 > audio01.pcm XMMS writes a file in the WAV format, while mpg123 converts the MP3 into raw PCM audio data. Both of these formats can be used with cdrecord to create audio CDs. You have to use raw PCM with &man.burncd.8;. If you use WAV files, you will notice a small tick sound at the beginning of each track, this sound is the header of the WAV file. You can simply remove the header of a WAV file with the utility SoX (it can be installed from the audio/sox port or package): &prompt.user; sox -t wav -r 44100 -s -w -c 2 track.wav track.raw Read for more information on using a CD burner in FreeBSD. Ross Lippert Contributed by Video Playback Video playback is a very new and rapidly developing application area. Be patient. Not everything is going to work as smoothly as it did with sound. Before you begin, you should know the model of the video card you have and the chip it uses. While XFree86 supports a wide variety of video cards, fewer give good playback performance. To obtain a list of extensions supported by the X server using your card use the command &man.xdpyinfo.1; while X11 is running. It is a good idea to have a short MPEG file which can be treated as a test file for evaluating various players and options. Since some DVD players will look for DVD media in /dev/dvd by default, or have this device name hardcoded in them, you might find it useful to make symbolic links to the proper devices: &prompt.root; ln -sf /dev/acd0c /dev/dvd &prompt.root; ln -sf /dev/racd0c /dev/rdvd On FreeBSD 5.X, which uses &man.devfs.5; there is a slightly different set of recommended links: &prompt.root; ln -sf /dev/acd0c /dev/dvd &prompt.root; ln -sf /dev/acd0c /dev/rdvd Additionally, DVD decryption, which requires invoking special DVD-ROM functions, requires write permission on the DVD devices. Some of the ports discussed rely on the following kernel options to build correctly. Before attempting to build, add these options to the kernel configuration file, build a new kernel, and reboot: option CPU_ENABLE_SSE option USER_LDT To enhance the shared memory X11 interface, it is recommended that the values of some &man.sysctl.8; variables should be increased: kern.ipc.shmmax=67108864 kern.ipc.shmall=32768 Determining Video capabilities XVideo SDL DGA kernel configuration options CPU_ENABLE_SSE kernel configuration options USER_LDT There are several possible ways to display video under X11. What will really work is largely hardware dependent. Each method described below will have varying quality across different hardware. Secondly, the rendering of video in X11 is a topic receiving a lot of attention lately, and with each version of XFree86 there may be significant improvement. A list of common video interfaces: X11: normal X11 output using shared memory. XVideo: an extension to the X11 interface which supports video in any X11 drawable. SDL: the Simple Directmedia Layer. DGA: the Direct Graphics Access. SVGAlib: low level console graphics layer. XVideo XFree86 4.X has an extension called XVideo (aka Xvideo, aka Xv, aka xv) which allows video to be directly displayed in drawable objects through a special acceleration. This extension provides very good quality playback even on low-end machines (for example my PIII 400 Mhz laptop). Unfortunately, the list of cards in which this feature is supported out of the box is currently: 3DFX Voodoo 3 Intel i810 and i815 some S3 chips (such as Savage/IX and Savage/MX) If your card is not one of these, do not be disappointed yet. XFree86 4.X adds new xv capabilities with each release A popular familiar graphics card with generally very good XFree86 performance, nVidia, has yet to release the specifications on their XVideo support to the XFree86 team. It may be some time before XFree86 fully support XVideo for these cards. . To check whether the extension is running, use xvinfo: &prompt.user; xvinfo XVideo is supported for your card if the result looks like: X-Video Extension version 2.2 screen #0 Adaptor #0: "Savage Streams Engine" number of ports: 1 port base: 43 operations supported: PutImage supported visuals: depth 16, visualID 0x22 depth 16, visualID 0x23 number of attributes: 5 "XV_COLORKEY" (range 0 to 16777215) client settable attribute client gettable attribute (current value is 2110) "XV_BRIGHTNESS" (range -128 to 127) client settable attribute client gettable attribute (current value is 0) "XV_CONTRAST" (range 0 to 255) client settable attribute client gettable attribute (current value is 128) "XV_SATURATION" (range 0 to 255) client settable attribute client gettable attribute (current value is 128) "XV_HUE" (range -180 to 180) client settable attribute client gettable attribute (current value is 0) maximum XvImage size: 1024 x 1024 Number of image formats: 7 id: 0x32595559 (YUY2) guid: 59555932-0000-0010-8000-00aa00389b71 bits per pixel: 16 number of planes: 1 type: YUV (packed) id: 0x32315659 (YV12) guid: 59563132-0000-0010-8000-00aa00389b71 bits per pixel: 12 number of planes: 3 type: YUV (planar) id: 0x30323449 (I420) guid: 49343230-0000-0010-8000-00aa00389b71 bits per pixel: 12 number of planes: 3 type: YUV (planar) id: 0x36315652 (RV16) guid: 52563135-0000-0000-0000-000000000000 bits per pixel: 16 number of planes: 1 type: RGB (packed) depth: 0 red, green, blue masks: 0x1f, 0x3e0, 0x7c00 id: 0x35315652 (RV15) guid: 52563136-0000-0000-0000-000000000000 bits per pixel: 16 number of planes: 1 type: RGB (packed) depth: 0 red, green, blue masks: 0x1f, 0x7e0, 0xf800 id: 0x31313259 (Y211) guid: 59323131-0000-0010-8000-00aa00389b71 bits per pixel: 6 number of planes: 3 type: YUV (packed) id: 0x0 guid: 00000000-0000-0000-0000-000000000000 bits per pixel: 0 number of planes: 0 type: RGB (packed) depth: 1 red, green, blue masks: 0x0, 0x0, 0x0 Also note that the formats listed (YUV2, YUV12, etc) are not present with every implementation of XVideo and their absence may hinder some players. If the result looks like: X-Video Extension version 2.2 screen #0 no adaptors present Then XVideo is probably not supported for your card. If XVideo is not supported for your card, this only means that it will be more difficult for your display to meet the computational demands of rendering video. Depending on your video card and processor, though, you might still be able to have a satisfying experience. You should probably read about ways of improving performance in the advanced reading . Simple Directmedia Layer The Simple Directmedia Layer, SDL, was intended to be a porting layers between Microsoft Windows, BeOS, and Unix, allowing cross-platform applications to be developed which made efficient use of sound and graphics. The SDL layer provides a low-level abstraction to the hardware which can sometimes be more efficient than the X11 interface. The SDL can be found at devel/sdl12 Direct Graphics Access Direct Graphics Access is an XFree86 extension which allows a program to bypass the X server and directly alter the framebuffer. Because it relies on a low level memory mapping to effect this sharing, programs using it must must be run as root. The DGA extension can be tested and benchmarked by &man.dga.1;. When dga is running, it changes the colors of the display whenever a key is pressed. To quit, use q. Ports and Packages Dealing with Video video ports video packages This section discusses the software available from the FreeBSD Ports Collection which can be used for video playback. Video playback is a very active area of software development, and the capabilities of various applications are bound to diverge somewhat from the descriptions given here. Firstly, it is important to know that most of the video applications which run on FreeBSD were developed as Linux applications, originating in the past year. For this reason, they are both very experimental and riddled with Linux-isms which might prevent them from working at full efficiency on FreeBSD. By experimental, I mean that you should expect re-encoders, players, and DVD decrypters to have some major bugs, or interoperability problems with other programs. Here is a short list of the sort of things I mean: An application cannot playback a file which another application produced. An application cannot playback a file which the application itself produced. The same application on two different machines, rebuilt on each machine for that machine, plays back the same file differently. A seemingly trivial filter like rescaling of the image size results in very bad artifacts from a buggy rescaling routine. An application always dumping core. Documentation is not installed with the port and can be found either on the web or under PORTPATH/work/ . By Linux-isms, I mean that there are some issues resulting from the way some standard libraries are implemented in the Linux distributions, or some features of the Linux kernel which have been assumed by the authors of the applications, because that is where the authors are primarily developing. These issues may not be noticed and worked around by the port maintainers which can lead to some problems like these: The use of /proc/cpuinfo to detect processor characteristics. A misuse of threads which causes a program to hang upon completion instead of truly terminating. Software not yet in the FreeBSD Ports Collection which is commonly used in conjunction with the application. So far, these application developers have been cooperative with port maintainers to minimize the work-arounds needed for port-ing. MPlayer MPlayer is a recently developed and rapidly developing video player. The goals of the MPlayer team are speed and flexibility on Linux and other Unices. The project was started when the team founder got fed up with bad playback performance on then available players. Some would say that interface has been sacrificed for streamlined design, but once you get used to the command line options and the key-stroke controls, it works very well. Building MPlayer MPlayer making MPlayer resides in multimedia/mplayer. MPlayer performs a variety of hardware checks during the build process, resulting in a binary which will not be portable from one system to another. Therefore, it is important to build it from ports and not to use a binary package. Additionally, a number of options can be specified in the make which echo at the start of the build. &prompt.root; cd /usr/ports/multimedia/mplayer &prompt.root; make You can enable additional compilation optimizations by defining WITH_OPTIMIZED_CFLAGS You can enable GTK GUI by defining WITH_GUI. You can enable DVD support by defining WITH_DVD. You can enable SVGALIB support by defining WITH_SVGALIB. You can enable VORBIS sound support by defining WITH_VORBIS. You can enable XAnim DLL support by defining WITH_XANIM. If you have x11-toolkits/gtk12 installed, then you might as well enable the GUI. Otherwise, it is not worth the effort. If you intend to play (possibly CSS encoded) DVD's with MPlayer you must enable the DVD support option here Unauthorized DVD playback is a serious criminal act in some countries. Check local laws before enabling this option. . Some reasonable options are: &prompt.root; make WITH_DVD=yes WITH_SVGALIB=yes As of this writing, the MPlayer port will build its HTML documentation and one executable, mplayer. It can also be made to build an encoder, mencoder, which is a tool for re-encoding video. A modification to the Makefile can enable it. It may be enabled by default in subsequent versions of the port. The HTML documentation to MPlayer is very informative. If the reader finds the information on video hardware and interfaces in the chapter lacking, the MPlayer documentation is a very thorough alternative. You should definitely take the time to read the documentation of MPlayer, if you are looking for information about video support in Unix. Using MPlayer MPlayer use Any user of MPlayer must set up a .mplayer subdirectory directory of her home directory. To create this necessary subdirectory, you can do the following: &prompt.user; cd /usr/ports/multimedia/mplayer &prompt.user; make install-user The command options for mplayer are listed in the manual page. For even more detail there is HTML documentation. In this section, we will give some of the common use cases. To play from file, such as testfile.avi through one of the various video interfaces set the : &prompt.user; mplayer -vo xv testfile.avi &prompt.user; mplayer -vo sdl testfile.avi &prompt.user; mplayer -vo x11 testfile.avi &prompt.root; mplayer -vo dga testfile.avi &prompt.root; mplayer -vo 'sdl:dga' testfile.avi It is worth trying all of these options, as their relative performance depends on many factors and will vary significantly with hardware. To play from a DVD, replace the testfile.avi with where <N> is the title number to play and DEVICE is the device node for the DVD-ROM. For example, to play title 3 from /dev/dvd: &prompt.root; mplayer -vo dga -dvd 2 /dev/dvd To stop, pause, advance and so on, consult the keybindings, which are output by running mplayer -h or read the manual page. Additional important options for playback are: which engages the fullscreen mode and which helps performance. In order for the mplayer command line to not become too large, the user can create a file .mplayer/config and set default options there: vo=xv fs=yes zoom=yes Finally, mplayer can be used to rip a DVD title into a .vob file. To dump out title 2 from a DVD: &prompt.root; mplayer -dumpstream -dumpfile out.vob -dvd 2 /dev/dvd The output file, out.vob, will be MPEG and can be manipulated by the other packages described in this section. mencoder mencoder If you opt to install mencoder when you build, be forewarned that it is still quite experimental. To use mencoder it is a good idea to familiarize yourself with the options from the HTML documentation. There is a manual page, but it is not very useful without the HTML. There are innummerable ways to improve quality, lower bitrate, and change formats, and some of these tricks may make the difference between good or bad performance. Here are a couple of examples to get you going. First a simple copy: &prompt.user; mencoder input.avi -oac copy -ovc copy -o output.avi It is easy to find examples where the output is unplayable even by mplayer. Thus, if you just want to rip to a file, stick to the in mplayer. To convert input.avi to the MPEG4 codec with MPEG3 audio encoding (audio/lame is required): &prompt.user; mencoder input.avi -oac mp3lame -lameopts br=192 \ -ovc lavc -lavcopts vcodec=mpeg4:vhq -o output.avi This has produced output playable by mplayer and xine. input.avi can be replaced with and run as root to re-encode a DVD title directly. Since you are likely to be dissatisfied with your results the first time around, it is recommended you dump the title to a file and work on the file. The xine Video Player The xine video player is a project of wide scope aiming not only at being an all in one video solution, but also in producing a reusable base library and a modular executable which can be extended with plugins. It comes both as a package and as a port, graphics/xine. The good news is that the above is pretty much true. The xine player is still very rough around the edges, but it is clearly off to a good start. In practice, xine requires either a fast CPU with a fast video card, or support for the XVideo extension. The GUI is usable, but a bit clumsy. As of this writing, there is no input module shipped with xine which will play CSS encoded DVD's. There are third party builds which do have modules for this built in them, but none of these are in the FreeBSD Ports Collection. Compared to MPlayer, xine does more for the user, but at the same time, takes some of the more fine-grained control away from the user. The xine video player also may perform much worse on the non-XVideo interfaces and has very few good alternatives to it. The xine FAQ highly recommends that you have a video card which supports it. The xine player can be started by itself: &prompt.user; xine The menus can then be used to open a file, or it can be started to play a file immediately without the GUI with the command: &prompt.user; xine -g -p mymovie.avi The transcode utilities The software transcode is not a player, but a suite of tools for re-encoding .avi and .mpg files. With transcode, one has the ability to merge video files, repair broken files, using command line tools with stdin/stdout stream interfaces. Like MPlayer, transcode is very experimental software which must be build from the port graphics/transcode. Using a great many options to the make command. I recommend: &prompt.root; make WITH_LIBMPEG2=yes If you plan to install multimedia/avifile, then add the WITH_AVIFILE option to your make command line, as shown here: &prompt.root; make WITH_AVIFILE=yes WITH_LIBMPEG2=yes Here are two examples of using transcode for video conversion which produce rescaled output. The first encodes the output to an openDIVX AVI file, while the second encodes to the much more portable MPEG format. &prompt.user; transcode -i input.vob -x vob -V -Z 320x240 \ -y opendivx -N 0x55 -o output.avi &prompt.user; transcode -i input.vob -x vob -V -Z 320x240 \ -y mpeg -N 0x55 -o output.tmp &prompt.user; tcmplex -o output.mpg -i output.tmp.m1v -p output.tmp.mpa -m 1 There is a manual page for transcode, but for the various tc* utilities (such as tcmplex) which are also installed, there is only a curt output. In comparison, transcode runs significantly slower than mencoder, but it has a better chance of producing a more widely playable file. I can play transcode MPEGs on older copies of Windows Media Player and Apple's Quicktime, for example. Further Reading I have no doubt that within a year, much that is in this chapter will be out of date. Video will probably be much less problematic to get working well and a port will be in the collection which turns a FreeBSD system into a DVD-playing, PVR, and virtual A/V studio. Until that day arrives, those who want to get the very most out of FreeBSD's A/V capabilities will have to cobble together knowledge from several FAQs and tutorials and use a few different applications. This section exists to give the reader some links to learn more in case this chapter was just helpful enough. The MPlayer documentation is very technically informative. These documents should probably be consulted by anyone wishing to obtain a high level of expertise with Unix video. The MPlayer mailing list is hostile to anyone who has not bothered to read the documentation, so if you plan on making bug reports to them, RTFM. The xine HOWTO contains a chapter on performance improvement which is general to all players. Finally, there are some other promising applications which the reader may try: Avifile which is also a port multimedia/avifile. Ogle which is also a port multimedia/ogle. Xtheater diff --git a/en_US.ISO8859-1/books/handbook/printing/chapter.sgml b/en_US.ISO8859-1/books/handbook/printing/chapter.sgml index eb0b8e9f67..bfe87af213 100644 --- a/en_US.ISO8859-1/books/handbook/printing/chapter.sgml +++ b/en_US.ISO8859-1/books/handbook/printing/chapter.sgml @@ -1,4936 +1,4936 @@ Sean Kelly Contributed by Jim Mock Restructured and updated by Printing Synopsis LPD spooling system printing FreeBSD can be used to print to a wide variety of printers, from the oldest impact printer to the latest laser printers, and everything in between, allowing you to produce high quality printed output from the applications you run. FreeBSD can also be configured to act as a print server on a network; in this capacity FreeBSD can receive print jobs from a variety of other computers, including other FreeBSD computers, Windows and MacOS hosts. FreeBSD will ensure that one job at a time is printed, and can keep statistics on which users and machines are doing the most printing, produce banner pages showing who's printout is who's, and more. After reading this chapter, you will know: How to configure the FreeBSD print spooler. How to install print filters, to handle special print jobs differently, including converting incoming documents to print formats that your printers understand. How to enable header, or banner pages on your printout. How to print to printers connected to other computers. How to print to printers connected directly to the network. How to control printer restrictions, including limiting the size of print jobs, and preventing certain users from printing. How to keep printer statistics, and account for printer usage. How to troubleshoot printing problems. Before reading this chapter, you should: Know how to configure and install a new kernel (). Introduction In order to use printers with FreeBSD, you will need to set them up to work with the Berkeley line printer spooling system, also known as the LPD spooling system. It is the standard printer control system in FreeBSD. This chapter introduces the LPD spooling system, often simply called LPD, and will guide you through its configuration. If you are already familiar with LPD or another printer spooling system, you may wish to skip to section Setting up the spooling system. LPD controls everything about a host's printers. It is responsible for a number of things: It controls access to attached printers and printers attached to other hosts on the network. print jobs It enables users to submit files to be printed; these submissions are known as jobs. It prevents multiple users from accessing a printer at the same time by maintaining a queue for each printer. It can print header pages (also known as banner or burst pages) so users can easily find jobs they have printed in a stack of printouts. It takes care of communications parameters for printers connected on serial ports. It can send jobs over the network to a LPD spooler on another host. It can run special filters to format jobs to be printed for various printer languages or printer capabilities. It can account for printer usage. Through a configuration file (/etc/printcap), and by providing the special filter programs, you can enable the LPD system to do all or some subset of the above for a great variety of printer hardware. Why You Should Use the Spooler If you are the sole user of your system, you may be wondering why you should bother with the spooler when you do not need access control, header pages, or printer accounting. While it is possible to enable direct access to a printer, you should use the spooler anyway since: LPD prints jobs in the background; you do not have to wait for data to be copied to the printer. TeX LPD can conveniently run a job to be printed through filters to add date/time headers or convert a special file format (such as a TeX DVI file) into a format the printer will understand. You will not have to do these steps manually. Many free and commercial programs that provide a print feature usually expect to talk to the spooler on your system. By setting up the spooling system, you will more easily support other software you may later add or already have. Basic Setup To use printers with the LPD spooling system, you will need to set up both your printer hardware and the LPD software. This document describes two levels of setup: See section Simple Printer Setup to learn how to connect a printer, tell LPD how to communicate with it, and print plain text files to the printer. See section Advanced Printer Setup to find out how to print a variety of special file formats, to print header pages, to print across a network, to control access to printers, and to do printer accounting. Simple Printer Setup This section tells how to configure printer hardware and the LPD software to use the printer. It teaches the basics: Section Hardware Setup gives some hints on connecting the printer to a port on your computer. Section Software Setup shows how to setup the LPD spooler configuration file (/etc/printcap). If you are setting up a printer that uses a network protocol to accept data to print instead of a serial or parallel interface, see Printers With Networked Data Stream Interfaces. Although this section is called Simple Printer Setup, it is actually fairly complex. Getting the printer to work with your computer and the LPD spooler is the hardest part. The advanced options like header pages and accounting are fairly easy once you get the printer working. Hardware Setup This section tells about the various ways you can connect a printer to your PC. It talks about the kinds of ports and cables, and also the kernel configuration you may need to enable FreeBSD to speak to the printer. If you have already connected your printer and have successfully printed with it under another operating system, you can probably skip to section Software Setup. Ports and Cables Nearly all printers you can get for a PC today support one or both of the following interfaces: printer serial Serial interfaces use a serial port on your computer to send data to the printer. Serial interfaces are common in the computer industry and cables are readily available and also easy to construct. Serial interfaces sometimes need special cables and might require you to configure somewhat complex communications options. printer parallel Parallel interfaces use a parallel port on your computer to send data to the printer. Parallel interfaces are common in the PC market. Cables are readily available but more difficult to construct by hand. There are usually no communications options with parallel interfaces, making their configuration exceedingly simple. centronics parallel printers Parallel interfaces are sometimes known as Centronics interfaces, named after the connector type on the printer. In general, serial interfaces are slower than parallel interfaces. Parallel interfaces usually offer just one-way communication (computer to printer) while serial gives you two-way. Many newer parallel ports and printers can communicate in both directions under FreeBSD when a IEEE1284 compliant cable is used. PostScript Usually, the only time you need two-way communication with the printer is if the printer speaks PostScript. PostScript printers can be very verbose. In fact, PostScript jobs are actually programs sent to the printer; they need not produce paper at all and may return results directly to the computer. PostScript also uses two-way communication to tell the computer about problems, such as errors in the PostScript program or paper jams. Your users may be appreciative of such information. Furthermore, the best way to do effective accounting with a PostScript printer requires two-way communication: you ask the printer for its page count (how many pages it has printed in its lifetime), then send the user's job, then ask again for its page count. Subtract the two values and you know how much paper to charge the user. Parallel Ports To hook up a printer using a parallel interface, connect the Centronics cable between the printer and the computer. The instructions that came with the printer, the computer, or both should give you complete guidance. Remember which parallel port you used on the computer. The first parallel port is /dev/ppc0 to FreeBSD; the second is /dev/ppc1, and so on. The printer device name uses the same scheme: /dev/lpt0 for the printer on the first parallel ports etc. Serial Ports To hook up a printer using a serial interface, connect the proper serial cable between the printer and the computer. The instructions that came with the printer, the computer, or both should give you complete guidance. If you are unsure what the proper serial cable is, you may wish to try one of the following alternatives: A modem cable connects each pin of the connector on one end of the cable straight through to its corresponding pin of the connector on the other end. This type of cable is also known as a DTE-to-DCE cable. null-modem cable A null-modem cable connects some pins straight through, swaps others (send data to receive data, for example), and shorts some internally in each connector hood. This type of cable is also known as a DTE-to-DTE cable. A serial printer cable, required for some unusual printers, is like the null-modem cable, but sends some signals to their counterparts instead of being internally shorted. baud rate parity flow control protocol You should also set up the communications parameters for the printer, usually through front-panel controls or DIP switches on the printer. Choose the highest bps (bits per second, sometimes baud rate) rate that both your computer and the printer can support. Choose 7 or 8 data bits; none, even, or odd parity; and 1 or 2 stop bits. Also choose a flow control protocol: either none, or XON/XOFF (also known as in-band or software) flow control. Remember these settings for the software configuration that follows. Software Setup This section describes the software setup necessary to print with the LPD spooling system in FreeBSD. Here is an outline of the steps involved: Configure your kernel, if necessary, for the port you are using for the printer; section Kernel Configuration tells you what you need to do. Set the communications mode for the parallel port, if you are using a parallel port; section Setting the Communication Mode for the Parallel Port gives details. Test if the operating system can send data to the printer. Section Checking Printer Communications gives some suggestions on how to do this. Set up LPD for the printer by modifying the file /etc/printcap. You will find out how to do this later in this chapter. Kernel Configuration The operating system kernel is compiled to work with a specific set of devices. The serial or parallel interface for your printer is a part of that set. Therefore, it might be necessary to add support for an additional serial or parallel port if your kernel is not already configured for one. To find out if the kernel you are currently using supports a serial interface, type: - &prompt.root; dmesg | grep sioN + &prompt.root; grep sioN /var/run/dmesg.boot Where N is the number of the serial port, starting from zero. If you see output similar to the following: sio2 at port 0x3e8-0x3ef irq 5 on isa sio2: type 16550A then the kernel supports the port. To find out if the kernel supports a parallel interface, type: - &prompt.root; dmesg | grep ppcN + &prompt.root; grep ppcN /var/run/dmesg.boot Where N is the number of the parallel port, starting from zero. If you see output similar to the following: ppc0: <Parallel port> at port 0x378-0x37f irq 7 on isa0 ppc0: SMC-like chipset (ECP/EPP/PS2/NIBBLE) in COMPATIBLE mode ppc0: FIFO with 16/16/8 bytes threshold then the kernel supports the port. You might have to reconfigure your kernel in order for the operating system to recognize and use the parallel or serial port you are using for the printer. To add support for a serial port, see the section on kernel configuration. To add support for a parallel port, see that section and the section that follows. Adding <filename>/dev</filename> Entries for the Ports FreeBSD 5.0 includes the devfs filesystem which automatically creates device nodes as needed. If you are running a version of FreeBSD with devfs enabled then you can safely skip this section. Even though the kernel may support communication along a serial or parallel port, you will still need a software interface through which programs running on the system can send and receive data. That is what entries in the /dev directory are for. To add a /dev entry for a port: Become root with the &man.su.1; command. Enter the root password when prompted. Change to the /dev directory: &prompt.root; cd /dev Type: &prompt.root; ./MAKEDEV port Where port is the device entry for the port you want to make. Use lpt0 for the printer on the first parallel port, lpt1 for the printer on the second port, and so on; use ttyd0 for the first serial port, ttyd1 for the second, and so on. Type: &prompt.root; ls -l port to make sure the device entry got created. Setting the Communication Mode for the Parallel Port When you are using the parallel interface, you can choose whether FreeBSD should use interrupt-driven or polled communication with the printer. The generic printer device driver (&man.lpt.4;) on FreeBSD 4.X and 5.X uses the &man.ppbus.4; system, which controls the port chipset with the &man.ppc.4; driver. The interrupt-driven method is the default with the GENERIC kernel. With this method, the operating system uses an IRQ line to determine when the printer is ready for data. The polled method directs the operating system to repeatedly ask the printer if it is ready for more data. When it responds ready, the kernel sends more data. The interrupt-driven method is usually somewhat faster but uses up a precious IRQ line. Some newer HP printers are claimed not to work correctly in interrupt mode, apparently due to some (not yet exactly understood) timing problem. These printers need polled mode. You should use whichever one works. Some printers will work in both modes, but are painfully slow in interrupt mode. You can set the communications mode in two ways: by configuring the kernel or by using the &man.lptcontrol.8; program. To set the communications mode by configuring the kernel: Edit your kernel configuration file. Look for an ppc0 entry. If you are setting up the second parallel port, use ppc1 instead. Use ppc2 for the third port, and so on. If you want interrupt-driven mode, for FreeBSD 4.X add the irq specifier: device ppc0 at isa? irq N Where N is the IRQ number for your computer's parallel port. For FreeBSD 5.X, edit the following line: hint.ppc.0.irq="N" in the /boot/device.hints file and replace N with the right IRQ number. The kernel configuration file must also contain the &man.ppc.4; driver: device ppc If you want polled mode, do not add the irq specifier: For FreeBSD 4.X, use the following line in your kernel configuration file: device ppc0 at isa? For FreeBSD 5.X, simply remove in your /boot/device.hints file, the following line: hint.ppc.0.irq="N" In some cases, this is not enough to put the port in polled mode under FreeBSD 5.X. Most of time it comes from &man.acpi.4; driver, this latter is able to probe and attach devices, and therefore, control the access mode to the printer port. You should check your &man.acpi.4; configuration to correct this problem. Save the file. Then configure, build, and install the kernel, then reboot. See kernel configuration for more details. To set the communications mode with &man.lptcontrol.8;: Type: &prompt.root; lptcontrol -i -d /dev/lptN to set interrupt-driven mode for lptN. Type: &prompt.root; lptcontrol -p -d /dev/lptN to set polled-mode for lptN. You could put these commands in your /etc/rc.local file to set the mode each time your system boots. See &man.lptcontrol.8; for more information. Checking Printer Communications Before proceeding to configure the spooling system, you should make sure the operating system can successfully send data to your printer. It is a lot easier to debug printer communication and the spooling system separately. To test the printer, we will send some text to it. For printers that can immediately print characters sent to them, the program &man.lptest.1; is perfect: it generates all 96 printable ASCII characters in 96 lines. PostScript For a PostScript (or other language-based) printer, we will need a more sophisticated test. A small PostScript program, such as the following, will suffice: %!PS 100 100 moveto 300 300 lineto stroke 310 310 moveto /Helvetica findfont 12 scalefont setfont (Is this thing working?) show showpage The above PostScript code can be placed into a file and used as shown in the examples appearing in the following sections. PCL When this document refers to a printer language, it is assuming a language like PostScript, and not Hewlett Packard's PCL. Although PCL has great functionality, you can intermingle plain text with its escape sequences. PostScript cannot directly print plain text, and that is the kind of printer language for which we must make special accommodations. Checking a Parallel Printer printer parallel This section tells you how to check if FreeBSD can communicate with a printer connected to a parallel port. To test a printer on a parallel port: Become root with &man.su.1;. Send data to the printer. If the printer can print plain text, then use &man.lptest.1;. Type: &prompt.root; lptest > /dev/lptN Where N is the number of the parallel port, starting from zero. If the printer understands PostScript or other printer language, then send a small program to the printer. Type: &prompt.root; cat > /dev/lptN Then, line by line, type the program carefully as you cannot edit a line once you have pressed RETURN or ENTER. When you have finished entering the program, press CONTROL+D, or whatever your end of file key is. Alternatively, you can put the program in a file and type: &prompt.root; cat file > /dev/lptN Where file is the name of the file containing the program you want to send to the printer. You should see something print. Do not worry if the text does not look right; we will fix such things later. Checking a Serial Printer printer serial This section tells you how to check if FreeBSD can communicate with a printer on a serial port. To test a printer on a serial port: Become root with &man.su.1;. Edit the file /etc/remote. Add the following entry: printer:dv=/dev/port:br#bps-rate:pa=parity bits-per-second serial port parity Where port is the device entry for the serial port (ttyd0, ttyd1, etc.), bps-rate is the bits-per-second rate at which the printer communicates, and parity is the parity required by the printer (either even, odd, none, or zero). Here is a sample entry for a printer connected via a serial line to the third serial port at 19200 bps with no parity: printer:dv=/dev/ttyd2:br#19200:pa=none Connect to the printer with &man.tip.1;. Type: &prompt.root; tip printer If this step does not work, edit the file /etc/remote again and try using /dev/cuaaN instead of /dev/ttydN. Send data to the printer. If the printer can print plain text, then use &man.lptest.1;. Type: &prompt.user; $lptest If the printer understands PostScript or other printer language, then send a small program to the printer. Type the program, line by line, very carefully as backspacing or other editing keys may be significant to the printer. You may also need to type a special end-of-file key for the printer so it knows it received the whole program. For PostScript printers, press CONTROL+D. Alternatively, you can put the program in a file and type: &prompt.user; >file Where file is the name of the file containing the program. After &man.tip.1; sends the file, press any required end-of-file key. You should see something print. Do not worry if the text does not look right; we will fix that later. Enabling the Spooler: The <filename>/etc/printcap</filename> File At this point, your printer should be hooked up, your kernel configured to communicate with it (if necessary), and you have been able to send some simple data to the printer. Now, we are ready to configure LPD to control access to your printer. You configure LPD by editing the file /etc/printcap. The LPD spooling system reads this file each time the spooler is used, so updates to the file take immediate effect. printer capabilities The format of the &man.printcap.5; file is straightforward. Use your favorite text editor to make changes to /etc/printcap. The format is identical to other capability files like /usr/share/misc/termcap and /etc/remote. For complete information about the format, see the &man.cgetent.3;. The simple spooler configuration consists of the following steps: Pick a name (and a few convenient aliases) for the printer, and put them in the /etc/printcap file; see the Naming the Printer section for more information on naming. header pages Turn off header pages (which are on by default) by inserting the sh capability; see the Suppressing Header Pages section for more information. Make a spooling directory, and specify its location with the sd capability; see the Making the Spooling Directory section for more information. Set the /dev entry to use for the printer, and note it in /etc/printcap with the lp capability; see the Identifying the Printer Device for more information. Also, if the printer is on a serial port, set up the communication parameters with the fs, fc, xs, and xc capabilities; which is discussed in the Configuring Spooler Communications Parameters section. Install a plain text input filter; see the Installing the Text Filter section for details. Test the setup by printing something with the &man.lpr.1; command. More details are available in the Trying It Out and Troubleshooting sections. Language-based printers, such as PostScript printers, cannot directly print plain text. The simple setup outlined above and described in the following sections assumes that if you are installing such a printer you will print only files that the printer can understand. Users often expect that they can print plain text to any of the printers installed on your system. Programs that interface to LPD to do their printing usually make the same assumption. If you are installing such a printer and want to be able to print jobs in the printer language and print plain text jobs, you are strongly urged to add an additional step to the simple setup outlined above: install an automatic plain-text-to-PostScript (or other printer language) conversion program. The section entitled Accommodating Plain Text Jobs on PostScript Printers tells how to do this. Naming the Printer The first (easy) step is to pick a name for your printer It really does not matter whether you choose functional or whimsical names since you can also provide a number of aliases for the printer. At least one of the printers specified in the /etc/printcap should have the alias lp. This is the default printer's name. If users do not have the PRINTER environment variable nor specify a printer name on the command line of any of the LPD commands, then lp will be the default printer they get to use. Also, it is common practice to make the last alias for a printer be a full description of the printer, including make and model. Once you have picked a name and some common aliases, put them in the /etc/printcap file. The name of the printer should start in the leftmost column. Separate each alias with a vertical bar and put a colon after the last alias. In the following example, we start with a skeletal /etc/printcap that defines two printers (a Diablo 630 line printer and a Panasonic KX-P4455 PostScript laser printer): # # /etc/printcap for host rose # rattan|line|diablo|lp|Diablo 630 Line Printer: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4: In this example, the first printer is named rattan and has as aliases line, diablo, lp, and Diablo 630 Line Printer. Since it has the alias lp, it is also the default printer. The second is named bamboo, and has as aliases ps, PS, S, panasonic, and Panasonic KX-P4455 PostScript v51.4. Suppressing Header Pages printing header pages The LPD spooling system will by default print a header page for each job. The header page contains the user name who requested the job, the host from which the job came, and the name of the job, in nice large letters. Unfortunately, all this extra text gets in the way of debugging the simple printer setup, so we will suppress header pages. To suppress header pages, add the sh capability to the entry for the printer in /etc/printcap. Here is an example /etc/printcap with sh added: # # /etc/printcap for host rose - no header pages anywhere # rattan|line|diablo|lp|Diablo 630 Line Printer:\ :sh: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh: Note how we used the correct format: the first line starts in the leftmost column, and subsequent lines are indented with a single TAB. Every line in an entry except the last ends in a backslash character. Making the Spooling Directory printer spool print jobs The next step in the simple spooler setup is to make a spooling directory, a directory where print jobs reside until they are printed, and where a number of other spooler support files live. Because of the variable nature of spooling directories, it is customary to put these directories under /var/spool. It is not necessary to backup the contents of spooling directories, either. Recreating them is as simple as running &man.mkdir.1;. It is also customary to make the directory with a name that is identical to the name of the printer, as shown below: &prompt.root; mkdir /var/spool/printer-name However, if you have a lot of printers on your network, you might want to put the spooling directories under a single directory that you reserve just for printing with LPD. We will do this for our two example printers rattan and bamboo: &prompt.root; mkdir /var/spool/lpd &prompt.root; mkdir /var/spool/lpd/rattan &prompt.root; mkdir /var/spool/lpd/bamboo If you are concerned about the privacy of jobs that users print, you might want to protect the spooling directory so it is not publicly accessible. Spooling directories should be owned and be readable, writable, and searchable by user daemon and group daemon, and no one else. We will do this for our example printers: &prompt.root; chown daemon:daemon /var/spool/lpd/rattan &prompt.root; chown daemon:daemon /var/spool/lpd/bamboo &prompt.root; chmod 770 /var/spool/lpd/rattan &prompt.root; chmod 770 /var/spool/lpd/bamboo Finally, you need to tell LPD about these directories using the /etc/printcap file. You specify the pathname of the spooling directory with the sd capability: # # /etc/printcap for host rose - added spooling directories # rattan|line|diablo|lp|Diablo 630 Line Printer:\ :sh:sd=/var/spool/lpd/rattan: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh:sd=/var/spool/lpd/bamboo: Note that the name of the printer starts in the first column but all other entries describing the printer should be indented with a tab and each line escaped with a backslash. If you do not specify a spooling directory with sd, the spooling system will use /var/spool/lpd as a default. Identifying the Printer Device In the Adding /dev Entries for the Ports section, we identified which entry in the /dev directory FreeBSD will use to communicate with the printer. Now, we tell LPD that information. When the spooling system has a job to print, it will open the specified device on behalf of the filter program (which is responsible for passing data to the printer). List the /dev entry pathname in the /etc/printcap file using the lp capability. In our running example, let us assume that rattan is on the first parallel port, and bamboo is on a sixth serial port; here are the additions to /etc/printcap: # # /etc/printcap for host rose - identified what devices to use # rattan|line|diablo|lp|Diablo 630 Line Printer:\ :sh:sd=/var/spool/lpd/rattan:\ :lp=/dev/lpt0: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh:sd=/var/spool/lpd/bamboo:\ :lp=/dev/ttyd5: If you do not specify the lp capability for a printer in your /etc/printcap file, LPD uses /dev/lp as a default. /dev/lp currently does not exist in FreeBSD. If the printer you are installing is connected to a parallel port, skip to the section entitled, Installing the Text Filter. Otherwise, be sure to follow the instructions in the next section. Configuring Spooler Communication Parameters printer serial For printers on serial ports, LPD can set up the bps rate, parity, and other serial communication parameters on behalf of the filter program that sends data to the printer. This is advantageous since: It lets you try different communication parameters by simply editing the /etc/printcap file; you do not have to recompile the filter program. It enables the spooling system to use the same filter program for multiple printers which may have different serial communication settings. The following /etc/printcap capabilities control serial communication parameters of the device listed in the lp capability: br#bps-rate Sets the communications speed of the device to bps-rate, where bps-rate can be 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, or 38400 bits-per-second. fc#clear-bits Clears the flag bits clear-bits in the sgttyb structure after opening the device. fs#set-bits Sets the flag bits set-bits in the sgttyb structure. xc#clear-bits Clears local mode bits clear-bits after opening the device. xs#set-bits Sets local mode bits set-bits. For more information on the bits for the fc, fs, xc, and xs capabilities, see the file /usr/include/sys/ioctl_compat.h. When LPD opens the device specified by the lp capability, it reads the flag bits in the sgttyb structure; it clears any bits in the fc capability, then sets bits in the fs capability, then applies the resultant setting. It does the same for the local mode bits as well. Let us add to our example printer on the sixth serial port. We will set the bps rate to 38400. For the flag bits, we will set the TANDEM, ANYP, LITOUT, FLUSHO, and PASS8 flags. For the local mode bits, we will set the LITOUT and PASS8 flags: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh:sd=/var/spool/lpd/bamboo:\ :lp=/dev/ttyd5:fs#0x82000c1:xs#0x820: Installing the Text Filter print filters We are now ready to tell LPD what text filter to use to send jobs to the printer. A text filter, also known as an input filter, is a program that LPD runs when it has a job to print. When LPD runs the text filter for a printer, it sets the filter's standard input to the job to print, and its standard output to the printer device specified with the lp capability. The filter is expected to read the job from standard input, perform any necessary translation for the printer, and write the results to standard output, which will get printed. For more information on the text filter, see the Filters section. For our simple printer setup, the text filter can be a small shell script that just executes /bin/cat to send the job to the printer. FreeBSD comes with another filter called lpf that handles backspacing and underlining for printers that might not deal with such character streams well. And, of course, you can use any other filter program you want. The filter lpf is described in detail in section entitled lpf: a Text Filter. First, let us make the shell script /usr/local/libexec/if-simple be a simple text filter. Put the following text into that file with your favorite text editor: #!/bin/sh # # if-simple - Simple text input filter for lpd # Installed in /usr/local/libexec/if-simple # # Simply copies stdin to stdout. Ignores all filter arguments. /bin/cat && exit 0 exit 2 Make the file executable: &prompt.root; chmod 555 /usr/local/libexec/if-simple And then tell LPD to use it by specifying it with the if capability in /etc/printcap. We will add it to the two printers we have so far in the example /etc/printcap: # # /etc/printcap for host rose - added text filter # rattan|line|diablo|lp|Diablo 630 Line Printer:\ :sh:sd=/var/spool/lpd/rattan:\ :lp=/dev/lpt0:\ :if=/usr/local/libexec/if-simple: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh:sd=/var/spool/lpd/bamboo:\ :lp=/dev/ttyd5:fs#0x82000e1:xs#0x820:\ :if=/usr/local/libexec/if-simple: Turn on <application>LPD</application> &man.lpd.8; is run from /etc/rc, controlled by the lpd_enable variable. This variable defaults to NO. If you have not done so already, add the line: lpd_enable="YES" to /etc/rc.conf, and then either restart your machine, or just run &man.lpd.8;. &prompt.root; lpd Trying It Out You have reached the end of the simple LPD setup. Unfortunately, congratulations are not quite yet in order, since we still have to test the setup and correct any problems. To test the setup, try printing something. To print with the LPD system, you use the command &man.lpr.1;, which submits a job for printing. You can combine &man.lpr.1; with the &man.lptest.1; program, introduced in section Checking Printer Communications to generate some test text. To test the simple LPD setup: Type: &prompt.root; lptest 20 5 | lpr -Pprinter-name Where printer-name is a the name of a printer (or an alias) specified in /etc/printcap. To test the default printer, type &man.lpr.1; without any argument. Again, if you are testing a printer that expects PostScript, send a PostScript program in that language instead of using &man.lptest.1;. You can do so by putting the program in a file and typing lpr file. For a PostScript printer, you should get the results of the program. If you are using &man.lptest.1;, then your results should look like the following: !"#$%&'()*+,-./01234 "#$%&'()*+,-./012345 #$%&'()*+,-./0123456 $%&'()*+,-./01234567 %&'()*+,-./012345678 To further test the printer, try downloading larger programs (for language-based printers) or running &man.lptest.1; with different arguments. For example, lptest 80 60 will produce 60 lines of 80 characters each. If the printer did not work, see the Troubleshooting section. Advanced Printer Setup This section describes filters for printing specially formatted files, header pages, printing across networks, and restricting and accounting for printer usage. Filters print filters Although LPD handles network protocols, queuing, access control, and other aspects of printing, most of the real work happens in the filters. Filters are programs that communicate with the printer and handle its device dependencies and special requirements. In the simple printer setup, we installed a plain text filter—an extremely simple one that should work with most printers (section Installing the Text Filter). However, in order to take advantage of format conversion, printer accounting, specific printer quirks, and so on, you should understand how filters work. It will ultimately be the filter's responsibility to handle these aspects. And the bad news is that most of the time you have to provide filters yourself. The good news is that many are generally available; when they are not, they are usually easy to write. Also, FreeBSD comes with one, /usr/libexec/lpr/lpf, that works with many printers that can print plain text. (It handles backspacing and tabs in the file, and does accounting, but that is about all it does.) There are also several filters and filter components in the FreeBSD Ports Collection. Here is what you will find in this section: Section How Filters Work, tries to give an overview of a filter's role in the printing process. You should read this section to get an understanding of what is happening under the hood when LPD uses filters. This knowledge could help you anticipate and debug problems you might encounter as you install more and more filters on each of your printers. LPD expects every printer to be able to print plain text by default. This presents a problem for PostScript (or other language-based printers) which cannot directly print plain text. Section Accommodating Plain Text Jobs on PostScript Printers tells you what you should do to overcome this problem. You should read this section if you have a PostScript printer. PostScript is a popular output format for many programs. Even some people (myself included) write PostScript code directly. But PostScript printers are expensive. Section Simulating PostScript on Non-PostScript Printers tells how you can further modify a printer's text filter to accept and print PostScript data on a non-PostScript printer. You should read this section if you do not have a PostScript printer. Section Conversion Filters tells about a way you can automate the conversion of specific file formats, such as graphic or typesetting data, into formats your printer can understand. After reading this section, you should be able to set up your printers such that users can type lpr -t to print troff data, or lpr -d to print TeX DVI data, or lpr -v to print raster image data, and so forth. I recommend reading this section. Section Output Filters tells all about a not often used feature of LPD: output filters. Unless you are printing header pages (see Header Pages), you can probably skip that section altogether. Section lpf: a Text Filter describes lpf, a fairly complete if simple text filter for line printers (and laser printers that act like line printers) that comes with FreeBSD. If you need a quick way to get printer accounting working for plain text, or if you have a printer which emits smoke when it sees backspace characters, you should definitely consider lpf. How Filters Work As mentioned before, a filter is an executable program started by LPD to handle the device-dependent part of communicating with the printer. When LPD wants to print a file in a job, it starts a filter program. It sets the filter's standard input to the file to print, its standard output to the printer, and its standard error to the error logging file (specified in the lf capability in /etc/printcap, or /dev/console by default). troff Which filter LPD starts and the filter's arguments depend on what is listed in the /etc/printcap file and what arguments the user specified for the job on the &man.lpr.1; command line. For example, if the user typed lpr -t, LPD would start the troff filter, listed in the tf capability for the destination printer. If the user wanted to print plain text, it would start the if filter (this is mostly true: see Output Filters for details). There are three kinds of filters you can specify in /etc/printcap: The text filter, confusingly called the input filter in LPD documentation, handles regular text printing. Think of it as the default filter. LPD expects every printer to be able to print plain text by default, and it is the text filter's job to make sure backspaces, tabs, or other special characters do not confuse the printer. If you are in an environment where you have to account for printer usage, the text filter must also account for pages printed, usually by counting the number of lines printed and comparing that to the number of lines per page the printer supports. The text filter is started with the following argument list: filter-name -c -wwidth -llength -iindent -n login -h host acct-file where appears if the job is submitted with lpr -l width is the value from the pw (page width) capability specified in /etc/printcap, default 132 length is the value from the pl (page length) capability, default 66 indent is the amount of the indentation from lpr -i, default 0 login is the account name of the user printing the file host is the host name from which the job was submitted acct-file is the name of the accounting file from the af capability. printer filters A conversion filter converts a specific file format into one the printer can render onto paper. For example, ditroff typesetting data cannot be directly printed, but you can install a conversion filter for ditroff files to convert the ditroff data into a form the printer can digest and print. Section Conversion Filters tells all about them. Conversion filters also need to do accounting, if you need printer accounting. Conversion filters are started with the following arguments: filter-name -xpixel-width -ypixel-height -n login -h host acct-file where pixel-width is the value from the px capability (default 0) and pixel-height is the value from the py capability (default 0). The output filter is used only if there is no text filter, or if header pages are enabled. In my experience, output filters are rarely used. Section Output Filters describe them. There are only two arguments to an output filter: filter-name -wwidth -llength which are identical to the text filters and arguments. Filters should also exit with the following exit status: exit 0 If the filter printed the file successfully. exit 1 If the filter failed to print the file but wants LPD to try to print the file again. LPD will restart a filter if it exits with this status. exit 2 If the filter failed to print the file and does not want LPD to try again. LPD will throw out the file. The text filter that comes with the FreeBSD release, /usr/libexec/lpr/lpf, takes advantage of the page width and length arguments to determine when to send a form feed and how to account for printer usage. It uses the login, host, and accounting file arguments to make the accounting entries. If you are shopping for filters, see if they are LPD-compatible. If they are, they must support the argument lists described above. If you plan on writing filters for general use, then have them support the same argument lists and exit codes. Accommodating Plain Text Jobs on PostScript Printers print jobs If you are the only user of your computer and PostScript (or other language-based) printer, and you promise to never send plain text to your printer and to never use features of various programs that will want to send plain text to your printer, then you do not need to worry about this section at all. But, if you would like to send both PostScript and plain text jobs to the printer, then you are urged to augment your printer setup. To do so, we have the text filter detect if the arriving job is plain text or PostScript. All PostScript jobs must start with %! (for other printer languages, see your printer documentation). If those are the first two characters in the job, we have PostScript, and can pass the rest of the job directly. If those are not the first two characters in the file, then the filter will convert the text into PostScript and print the result. How do we do this? printer serial If you have got a serial printer, a great way to do it is to install lprps. lprps is a PostScript printer filter which performs two-way communication with the printer. It updates the printer's status file with verbose information from the printer, so users and administrators can see exactly what the state of the printer is (such as toner low or paper jam). But more importantly, it includes a program called psif which detects whether the incoming job is plain text and calls textps (another program that comes with lprps) to convert it to PostScript. It then uses lprps to send the job to the printer. lprps is part of the FreeBSD Ports Collection (see The Ports Collection). You can fetch, build and install it yourself, of course. After installing lprps, just specify the pathname to the psif program that is part of lprps. If you installed lprps from the ports collection, use the following in the serial PostScript printer's entry in /etc/printcap: :if=/usr/local/libexec/psif: You should also specify the rw capability; that tells LPD to open the printer in read-write mode. If you have a parallel PostScript printer (and therefore cannot use two-way communication with the printer, which lprps needs), you can use the following shell script as the text filter: #!/bin/sh # # psif - Print PostScript or plain text on a PostScript printer # Script version; NOT the version that comes with lprps # Installed in /usr/local/libexec/psif # IFS="" read -r first_line first_two_chars=`expr "$first_line" : '\(..\)'` if [ "$first_two_chars" = "%!" ]; then # # PostScript job, print it. # echo "$first_line" && cat && printf "\004" && exit 0 exit 2 else # # Plain text, convert it, then print it. # ( echo "$first_line"; cat ) | /usr/local/bin/textps && printf "\004" && exit 0 exit 2 fi In the above script, textps is a program we installed separately to convert plain text to PostScript. You can use any text-to-PostScript program you wish. The FreeBSD Ports Collection (see The Ports Collection) includes a full featured text-to-PostScript program called a2ps that you might want to investigate. Simulating PostScript on Non-PostScript Printers PostScript emulating Ghostscript PostScript is the de facto standard for high quality typesetting and printing. PostScript is, however, an expensive standard. Thankfully, Alladin Enterprises has a free PostScript work-alike called Ghostscript that runs with FreeBSD. Ghostscript can read most PostScript files and can render their pages onto a variety of devices, including many brands of non-PostScript printers. By installing Ghostscript and using a special text filter for your printer, you can make your non-PostScript printer act like a real PostScript printer. Ghostscript is in the FreeBSD Ports Collection, if you would like to install it from there. You can fetch, build, and install it quite easily yourself, as well. To simulate PostScript, we have the text filter detect if it is printing a PostScript file. If it is not, then the filter will pass the file directly to the printer; otherwise, it will use Ghostscript to first convert the file into a format the printer will understand. Here is an example: the following script is a text filter for Hewlett Packard DeskJet 500 printers. For other printers, substitute the argument to the gs (Ghostscript) command. (Type gs -h to get a list of devices the current installation of Ghostscript supports.) #!/bin/sh # # ifhp - Print Ghostscript-simulated PostScript on a DeskJet 500 # Installed in /usr/local/libexec/hpif # # Treat LF as CR+LF: # printf "\033&k2G" || exit 2 # # Read first two characters of the file # IFS="" read -r first_line first_two_chars=`expr "$first_line" : '\(..\)'` if [ "$first_two_chars" = "%!" ]; then # # It is PostScript; use Ghostscript to scan-convert and print it. # # Note that PostScript files are actually interpreted programs, # and those programs are allowed to write to stdout, which will # mess up the printed output. So, we redirect stdout to stderr # and then make descriptor 3 go to stdout, and have Ghostscript # write its output there. Exercise for the clever reader: # capture the stderr output from Ghostscript and mail it back to # the user originating the print job. # exec 3>&1 1>&2 /usr/local/bin/gs -dSAFER -dNOPAUSE -q -sDEVICE=djet500 \ -sOutputFile=/dev/fd/3 - && exit 0 # /usr/local/bin/gs -dSAFER -dNOPAUSE -q -sDEVICE=djet500 -sOutputFile=- - \ && exit 0 else # # Plain text or HP/PCL, so just print it directly; print a form feed # at the end to eject the last page. # echo "$first_line" && cat && printf "\033&l0H" && exit 0 fi exit 2 Finally, you need to notify LPD of the filter via the if capability: :if=/usr/local/libexec/ifhp: That is it. You can type lpr plain.text and lpr whatever.ps and both should print successfully. Conversion Filters After completing the simple setup described in Simple Printer Setup, the first thing you will probably want to do is install conversion filters for your favorite file formats (besides plain ASCII text). Why Install Conversion Filters? TeX printing dvi files Conversion filters make printing various kinds of files easy. As an example, suppose we do a lot of work with the TeX typesetting system, and we have a PostScript printer. Every time we generate a DVI file from TeX, we cannot print it directly until we convert the DVI file into PostScript. The command sequence goes like this: &prompt.user; dvips seaweed-analysis.dvi &prompt.user; lpr seaweed-analysis.ps By installing a conversion filter for DVI files, we can skip the hand conversion step each time by having LPD do it for us. Now, each time we get a DVI file, we are just one step away from printing it: &prompt.user; lpr -d seaweed-analysis.dvi We got LPD to do the DVI file conversion for us by specifying the option. Section Formatting and Conversion Options lists the conversion options. For each of the conversion options you want a printer to support, install a conversion filter and specify its pathname in /etc/printcap. A conversion filter is like the text filter for the simple printer setup (see section Installing the Text Filter) except that instead of printing plain text, the filter converts the file into a format the printer can understand. Which Conversions Filters Should I Install? You should install the conversion filters you expect to use. If you print a lot of DVI data, then a DVI conversion filter is in order. If you have got plenty of troff to print out, then you probably want a troff filter. The following table summarizes the filters that LPD works with, their capability entries for the /etc/printcap file, and how to invoke them with the lpr command: File type /etc/printcap capability lpr option cifplot cf DVI df plot gf ditroff nf FORTRAN text rf troff rf raster vf plain text if none, , or In our example, using lpr -d means the printer needs a df capability in its entry in /etc/printcap. fortran Despite what others might contend, formats like FORTRAN text and plot are probably obsolete. At your site, you can give new meanings to these or any of the formatting options just by installing custom filters. For example, suppose you would like to directly print Printerleaf files (files from the Interleaf desktop publishing program), but will never print plot files. You could install a Printerleaf conversion filter under the gf capability and then educate your users that lpr -g mean print Printerleaf files. Installing Conversion Filters Since conversion filters are programs you install outside of the base FreeBSD installation, they should probably go under /usr/local. The directory /usr/local/libexec is a popular location, since they are specialized programs that only LPD will run; regular users should not ever need to run them. To enable a conversion filter, specify its pathname under the appropriate capability for the destination printer in /etc/printcap. In our example, we will add the DVI conversion filter to the entry for the printer named bamboo. Here is the example /etc/printcap file again, with the new df capability for the printer bamboo. # # /etc/printcap for host rose - added df filter for bamboo # rattan|line|diablo|lp|Diablo 630 Line Printer:\ :sh:sd=/var/spool/lpd/rattan:\ :lp=/dev/lpt0:\ :if=/usr/local/libexec/if-simple: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh:sd=/var/spool/lpd/bamboo:\ :lp=/dev/ttyd5:fs#0x82000e1:xs#0x820:rw:\ :if=/usr/local/libexec/psif:\ :df=/usr/local/libexec/psdf: The DVI filter is a shell script named /usr/local/libexec/psdf. Here is that script: #!/bin/sh # # psdf - DVI to PostScript printer filter # Installed in /usr/local/libexec/psdf # # Invoked by lpd when user runs lpr -d # exec /usr/local/bin/dvips -f | /usr/local/libexec/lprps "$@" This script runs dvips in filter mode (the argument) on standard input, which is the job to print. It then starts the PostScript printer filter lprps (see section Accommodating Plain Text Jobs on PostScript Printers) with the arguments LPD passed to this script. lprps will use those arguments to account for the pages printed. More Conversion Filter Examples Since there is no fixed set of steps to install conversion filters, let me instead provide more examples. Use these as guidance to making your own filters. Use them directly, if appropriate. This example script is a raster (well, GIF file, actually) conversion filter for a Hewlett Packard LaserJet III-Si printer: #!/bin/sh # # hpvf - Convert GIF files into HP/PCL, then print # Installed in /usr/local/libexec/hpvf PATH=/usr/X11R6/bin:$PATH; export PATH giftopnm | ppmtopgm | pgmtopbm | pbmtolj -resolution 300 \ && exit 0 \ || exit 2 It works by converting the GIF file into a portable anymap, converting that into a portable graymap, converting that into a portable bitmap, and converting that into LaserJet/PCL-compatible data. Here is the /etc/printcap file with an entry for a printer using the above filter: # # /etc/printcap for host orchid # teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\ :lp=/dev/lpt0:sh:sd=/var/spool/lpd/teak:mx#0:\ :if=/usr/local/libexec/hpif:\ :vf=/usr/local/libexec/hpvf: The following script is a conversion filter for troff data from the groff typesetting system for the PostScript printer named bamboo: #!/bin/sh # # pstf - Convert groff's troff data into PS, then print. # Installed in /usr/local/libexec/pstf # exec grops | /usr/local/libexec/lprps "$@" The above script makes use of lprps again to handle the communication with the printer. If the printer were on a parallel port, we would use this script instead: #!/bin/sh # # pstf - Convert groff's troff data into PS, then print. # Installed in /usr/local/libexec/pstf # exec grops That is it. Here is the entry we need to add to /etc/printcap to enable the filter: :tf=/usr/local/libexec/pstf: Here is an example that might make old hands at FORTRAN blush. It is a FORTRAN-text filter for any printer that can directly print plain text. We will install it for the printer teak: #!/bin/sh # # hprf - FORTRAN text filter for LaserJet 3si: # Installed in /usr/local/libexec/hprf # printf "\033&k2G" && fpr && printf "\033&l0H" && exit 0 exit 2 And we will add this line to the /etc/printcap for the printer teak to enable this filter: :rf=/usr/local/libexec/hprf: Here is one final, somewhat complex example. We will add a DVI filter to the LaserJet printer teak introduced earlier. First, the easy part: updating /etc/printcap with the location of the DVI filter: :df=/usr/local/libexec/hpdf: Now, for the hard part: making the filter. For that, we need a DVI-to-LaserJet/PCL conversion program. The FreeBSD Ports Collection (see The Ports Collection) has one: dvi2xx is the name of the package. Installing this package gives us the program we need, dvilj2p, which converts DVI into LaserJet IIp, LaserJet III, and LaserJet 2000 compatible codes. dvilj2p makes the filter hpdf quite complex since dvilj2p cannot read from standard input. It wants to work with a filename. What is worse, the filename has to end in .dvi so using /dev/fd/0 for standard input is problematic. We can get around that problem by linking (symbolically) a temporary file name (one that ends in .dvi) to /dev/fd/0, thereby forcing dvilj2p to read from standard input. The only other fly in the ointment is the fact that we cannot use /tmp for the temporary link. Symbolic links are owned by user and group bin. The filter runs as user daemon. And the /tmp directory has the sticky bit set. The filter can create the link, but it will not be able clean up when done and remove it since the link will belong to a different user. Instead, the filter will make the symbolic link in the current working directory, which is the spooling directory (specified by the sd capability in /etc/printcap). This is a perfect place for filters to do their work, especially since there is (sometimes) more free disk space in the spooling directory than under /tmp. Here, finally, is the filter: #!/bin/sh # # hpdf - Print DVI data on HP/PCL printer # Installed in /usr/local/libexec/hpdf PATH=/usr/local/bin:$PATH; export PATH # # Define a function to clean up our temporary files. These exist # in the current directory, which will be the spooling directory # for the printer. # cleanup() { rm -f hpdf$$.dvi } # # Define a function to handle fatal errors: print the given message # and exit 2. Exiting with 2 tells LPD to do not try to reprint the # job. # fatal() { echo "$@" 1>&2 cleanup exit 2 } # # If user removes the job, LPD will send SIGINT, so trap SIGINT # (and a few other signals) to clean up after ourselves. # trap cleanup 1 2 15 # # Make sure we are not colliding with any existing files. # cleanup # # Link the DVI input file to standard input (the file to print). # ln -s /dev/fd/0 hpdf$$.dvi || fatal "Cannot symlink /dev/fd/0" # # Make LF = CR+LF # printf "\033&k2G" || fatal "Cannot initialize printer" # # Convert and print. Return value from dvilj2p does not seem to be # reliable, so we ignore it. # dvilj2p -M1 -q -e- dfhp$$.dvi # # Clean up and exit # cleanup exit 0 Automated Conversion: An Alternative To Conversion Filters All these conversion filters accomplish a lot for your printing environment, but at the cost forcing the user to specify (on the &man.lpr.1; command line) which one to use. If your users are not particularly computer literate, having to specify a filter option will become annoying. What is worse, though, is that an incorrectly specified filter option may run a filter on the wrong type of file and cause your printer to spew out hundreds of sheets of paper. Rather than install conversion filters at all, you might want to try having the text filter (since it is the default filter) detect the type of file it has been asked to print and then automatically run the right conversion filter. Tools such as file can be of help here. Of course, it will be hard to determine the differences between some file types—and, of course, you can still provide conversion filters just for them. apsfilter printer filters apsfilter The FreeBSD Ports Collection has a text filter that performs automatic conversion called apsfilter. It can detect plain text, PostScript, and DVI files, run the proper conversions, and print. Output Filters The LPD spooling system supports one other type of filter that we have not yet explored: an output filter. An output filter is intended for printing plain text only, like the text filter, but with many simplifications. If you are using an output filter but no text filter, then: LPD starts an output filter once for the entire job instead of once for each file in the job. LPD does not make any provision to identify the start or the end of files within the job for the output filter. LPD does not pass the user's login or host to the filter, so it is not intended to do accounting. In fact, it gets only two arguments: filter-name -wwidth -llength Where width is from the pw capability and length is from the pl capability for the printer in question. Do not be seduced by an output filter's simplicity. If you would like each file in a job to start on a different page an output filter will not work. Use a text filter (also known as an input filter); see section Installing the Text Filter. Furthermore, an output filter is actually more complex in that it has to examine the byte stream being sent to it for special flag characters and must send signals to itself on behalf of LPD. However, an output filter is necessary if you want header pages and need to send escape sequences or other initialization strings to be able to print the header page. (But it is also futile if you want to charge header pages to the requesting user's account, since LPD does not give any user or host information to the output filter.) On a single printer, LPD allows both an output filter and text or other filters. In such cases, LPD will start the output filter to print the header page (see section Header Pages) only. LPD then expects the output filter to stop itself by sending two bytes to the filter: ASCII 031 followed by ASCII 001. When an output filter sees these two bytes (031, 001), it should stop by sending SIGSTOP to itself. When LPD's done running other filters, it will restart the output filter by sending SIGCONT to it. If there is an output filter but no text filter and LPD is working on a plain text job, LPD uses the output filter to do the job. As stated before, the output filter will print each file of the job in sequence with no intervening form feeds or other paper advancement, and this is probably not what you want. In almost all cases, you need a text filter. The program lpf, which we introduced earlier as a text filter, can also run as an output filter. If you need a quick-and-dirty output filter but do not want to write the byte detection and signal sending code, try lpf. You can also wrap lpf in a shell script to handle any initialization codes the printer might require. <command>lpf</command>: a Text Filter The program /usr/libexec/lpr/lpf that comes with FreeBSD binary distribution is a text filter (input filter) that can indent output (job submitted with lpr -i), allow literal characters to pass (job submitted with lpr -l), adjust the printing position for backspaces and tabs in the job, and account for pages printed. It can also act like an output filter. lpf is suitable for many printing environments. And although it has no capability to send initialization sequences to a printer, it is easy to write a shell script to do the needed initialization and then execute lpf. page accounting accounting printer In order for lpf to do page accounting correctly, it needs correct values filled in for the pw and pl capabilities in the /etc/printcap file. It uses these values to determine how much text can fit on a page and how many pages were in a user's job. For more information on printer accounting, see Accounting for Printer Usage. Header Pages If you have lots of users, all of them using various printers, then you probably want to consider header pages as a necessary evil. banner pages header pages header pages Header pages, also known as banner or burst pages identify to whom jobs belong after they are printed. They are usually printed in large, bold letters, perhaps with decorative borders, so that in a stack of printouts they stand out from the real documents that comprise users' jobs. They enable users to locate their jobs quickly. The obvious drawback to a header page is that it is yet one more sheet that has to be printed for every job, their ephemeral usefulness lasting not more than a few minutes, ultimately finding themselves in a recycling bin or rubbish heap. (Note that header pages go with each job, not each file in a job, so the paper waste might not be that bad.) The LPD system can provide header pages automatically for your printouts if your printer can directly print plain text. If you have a PostScript printer, you will need an external program to generate the header page; see Header Pages on PostScript Printers. Enabling Header Pages In the Simple Printer Setup section, we turned off header pages by specifying sh (meaning suppress header) in the /etc/printcap file. To enable header pages for a printer, just remove the sh capability. Sounds too easy, right? You are right. You might have to provide an output filter to send initialization strings to the printer. Here is an example output filter for Hewlett Packard PCL-compatible printers: #!/bin/sh # # hpof - Output filter for Hewlett Packard PCL-compatible printers # Installed in /usr/local/libexec/hpof printf "\033&k2G" || exit 2 exec /usr/libexec/lpr/lpf Specify the path to the output filter in the of capability. See the Output Filters section for more information. Here is an example /etc/printcap file for the printer teak that we introduced earlier; we enabled header pages and added the above output filter: # # /etc/printcap for host orchid # teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\ :lp=/dev/lpt0:sd=/var/spool/lpd/teak:mx#0:\ :if=/usr/local/libexec/hpif:\ :vf=/usr/local/libexec/hpvf:\ :of=/usr/local/libexec/hpof: Now, when users print jobs to teak, they get a header page with each job. If users want to spend time searching for their printouts, they can suppress header pages by submitting the job with lpr -h; see the Header Page Options section for more &man.lpr.1; options. LPD prints a form feed character after the header page. If your printer uses a different character or sequence of characters to eject a page, specify them with the ff capability in /etc/printcap. Controlling Header Pages By enabling header pages, LPD will produce a long header, a full page of large letters identifying the user, host, and job. Here is an example (kelly printed the job named outline from host rose): k ll ll k l l k l l k k eeee l l y y k k e e l l y y k k eeeeee l l y y kk k e l l y y k k e e l l y yy k k eeee lll lll yyy y y y y yyyy ll t l i t l oooo u u ttttt l ii n nnn eeee o o u u t l i nn n e e o o u u t l i n n eeeeee o o u u t l i n n e o o u uu t t l i n n e e oooo uuu u tt lll iii n n eeee r rrr oooo ssss eeee rr r o o s s e e r o o ss eeeeee r o o ss e r o o s s e e r oooo ssss eeee Job: outline Date: Sun Sep 17 11:04:58 1995 LPD appends a form feed after this text so the job starts on a new page (unless you have sf (suppress form feeds) in the destination printer's entry in /etc/printcap). If you prefer, LPD can make a short header; specify sb (short banner) in the /etc/printcap file. The header page will look like this: rose:kelly Job: outline Date: Sun Sep 17 11:07:51 1995 Also by default, LPD prints the header page first, then the job. To reverse that, specify hl (header last) in /etc/printcap. Accounting for Header Pages Using LPD's built-in header pages enforces a particular paradigm when it comes to printer accounting: header pages must be free of charge. Why? Because the output filter is the only external program that will have control when the header page is printed that could do accounting, and it is not provided with any user or host information or an accounting file, so it has no idea whom to charge for printer use. It is also not enough to just add one page to the text filter or any of the conversion filters (which do have user and host information) since users can suppress header pages with lpr -h. They could still be charged for header pages they did not print. Basically, lpr -h will be the preferred option of environmentally-minded users, but you cannot offer any incentive to use it. It is still not enough to have each of the filters generate their own header pages (thereby being able to charge for them). If users wanted the option of suppressing the header pages with lpr -h, they will still get them and be charged for them since LPD does not pass any knowledge of the option to any of the filters. So, what are your options? You can: Accept LPD's paradigm and make header pages free. Install an alternative to LPD, such as LPRng. Section Alternatives to the Standard Spooler tells more about other spooling software you can substitute for LPD. Write a smart output filter. Normally, an output filter is not meant to do anything more than initialize a printer or do some simple character conversion. It is suited for header pages and plain text jobs (when there is no text (input) filter). But, if there is a text filter for the plain text jobs, then LPD will start the output filter only for the header pages. And the output filter can parse the header page text that LPD generates to determine what user and host to charge for the header page. The only other problem with this method is that the output filter still does not know what accounting file to use (it is not passed the name of the file from the af capability), but if you have a well-known accounting file, you can hard-code that into the output filter. To facilitate the parsing step, use the sh (short header) capability in /etc/printcap. Then again, all that might be too much trouble, and users will certainly appreciate the more generous system administrator who makes header pages free. Header Pages on PostScript Printers As described above, LPD can generate a plain text header page suitable for many printers. Of course, PostScript cannot directly print plain text, so the header page feature of LPD is useless—or mostly so. One obvious way to get header pages is to have every conversion filter and the text filter generate the header page. The filters should use the user and host arguments to generate a suitable header page. The drawback of this method is that users will always get a header page, even if they submit jobs with lpr -h. Let us explore this method. The following script takes three arguments (user login name, host name, and job name) and makes a simple PostScript header page: #!/bin/sh # # make-ps-header - make a PostScript header page on stdout # Installed in /usr/local/libexec/make-ps-header # # # These are PostScript units (72 to the inch). Modify for A4 or # whatever size paper you are using: # page_width=612 page_height=792 border=72 # # Check arguments # if [ $# -ne 3 ]; then echo "Usage: `basename $0` <user> <host> <job>" 1>&2 exit 1 fi # # Save these, mostly for readability in the PostScript, below. # user=$1 host=$2 job=$3 date=`date` # # Send the PostScript code to stdout. # exec cat <<EOF %!PS % % Make sure we do not interfere with user's job that will follow % save % % Make a thick, unpleasant border around the edge of the paper. % $border $border moveto $page_width $border 2 mul sub 0 rlineto 0 $page_height $border 2 mul sub rlineto currentscreen 3 -1 roll pop 100 3 1 roll setscreen $border 2 mul $page_width sub 0 rlineto closepath 0.8 setgray 10 setlinewidth stroke 0 setgray % % Display user's login name, nice and large and prominent % /Helvetica-Bold findfont 64 scalefont setfont $page_width ($user) stringwidth pop sub 2 div $page_height 200 sub moveto ($user) show % % Now show the boring particulars % /Helvetica findfont 14 scalefont setfont /y 200 def [ (Job:) (Host:) (Date:) ] { 200 y moveto show /y y 18 sub def } forall /Helvetica-Bold findfont 14 scalefont setfont /y 200 def [ ($job) ($host) ($date) ] { 270 y moveto show /y y 18 sub def } forall % % That is it % restore showpage EOF Now, each of the conversion filters and the text filter can call this script to first generate the header page, and then print the user's job. Here is the DVI conversion filter from earlier in this document, modified to make a header page: #!/bin/sh # # psdf - DVI to PostScript printer filter # Installed in /usr/local/libexec/psdf # # Invoked by lpd when user runs lpr -d # orig_args="$@" fail() { echo "$@" 1>&2 exit 2 } while getopts "x:y:n:h:" option; do case $option in x|y) ;; # Ignore n) login=$OPTARG ;; h) host=$OPTARG ;; *) echo "LPD started `basename $0` wrong." 1>&2 exit 2 ;; esac done [ "$login" ] || fail "No login name" [ "$host" ] || fail "No host name" ( /usr/local/libexec/make-ps-header $login $host "DVI File" /usr/local/bin/dvips -f ) | eval /usr/local/libexec/lprps $orig_args Notice how the filter has to parse the argument list in order to determine the user and host name. The parsing for the other conversion filters is identical. The text filter takes a slightly different set of arguments, though (see section How Filters Work). As we have mentioned before, the above scheme, though fairly simple, disables the suppress header page option (the option) to lpr. If users wanted to save a tree (or a few pennies, if you charge for header pages), they would not be able to do so, since every filter's going to print a header page with every job. To allow users to shut off header pages on a per-job basis, you will need to use the trick introduced in section Accounting for Header Pages: write an output filter that parses the LPD-generated header page and produces a PostScript version. If the user submits the job with lpr -h, then LPD will not generate a header page, and neither will your output filter. Otherwise, your output filter will read the text from LPD and send the appropriate header page PostScript code to the printer. If you have a PostScript printer on a serial line, you can make use of lprps, which comes with an output filter, psof, which does the above. Note that psof does not charge for header pages. Networked Printing printer network network printing FreeBSD supports networked printing: sending jobs to remote printers. Networked printing generally refers to two different things: Accessing a printer attached to a remote host. You install a printer that has a conventional serial or parallel interface on one host. Then, you set up LPD to enable access to the printer from other hosts on the network. Section Printers Installed on Remote Hosts tells how to do this. Accessing a printer attached directly to a network. The printer has a network interface in addition (or in place of) a more conventional serial or parallel interface. Such a printer might work as follows: It might understand the LPD protocol and can even queue jobs from remote hosts. In this case, it acts just like a regular host running LPD. Follow the same procedure in section Printers Installed on Remote Hosts to set up such a printer. It might support a data stream network connection. In this case, you attach the printer to one host on the network by making that host responsible for spooling jobs and sending them to the printer. Section Printers with Networked Data Stream Interfaces gives some suggestions on installing such printers. Printers Installed on Remote Hosts The LPD spooling system has built-in support for sending jobs to other hosts also running LPD (or are compatible with LPD). This feature enables you to install a printer on one host and make it accessible from other hosts. It also works with printers that have network interfaces that understand the LPD protocol. To enable this kind of remote printing, first install a printer on one host, the printer host, using the simple printer setup described in the Simple Printer Setup section. Do any advanced setup in Advanced Printer Setup that you need. Make sure to test the printer and see if it works with the features of LPD you have enabled. Also ensure that the local host has authorization to use the LPD service in the remote host (see Restricting Jobs from Remote Printers). printer network network printing If you are using a printer with a network interface that is compatible with LPD, then the printer host in the discussion below is the printer itself, and the printer name is the name you configured for the printer. See the documentation that accompanied your printer and/or printer-network interface. If you are using a Hewlett Packard Laserjet then the printer name text will automatically perform the LF to CRLF conversion for you, so you will not require the hpif script. Then, on the other hosts you want to have access to the printer, make an entry in their /etc/printcap files with the following: Name the entry anything you want. For simplicity, though, you probably want to use the same name and aliases as on the printer host. Leave the lp capability blank, explicitly (:lp=:). Make a spooling directory and specify its location in the sd capability. LPD will store jobs here before they get sent to the printer host. Place the name of the printer host in the rm capability. Place the printer name on the printer host in the rp capability. That is it. You do not need to list conversion filters, page dimensions, or anything else in the /etc/printcap file. Here is an example. The host rose has two printers, bamboo and rattan. We will enable users on the host orchid to print to those printers. Here is the /etc/printcap file for orchid (back from section Enabling Header Pages). It already had the entry for the printer teak; we have added entries for the two printers on the host rose: # # /etc/printcap for host orchid - added (remote) printers on rose # # # teak is local; it is connected directly to orchid: # teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\ :lp=/dev/lpt0:sd=/var/spool/lpd/teak:mx#0:\ :if=/usr/local/libexec/ifhp:\ :vf=/usr/local/libexec/vfhp:\ :of=/usr/local/libexec/ofhp: # # rattan is connected to rose; send jobs for rattan to rose: # rattan|line|diablo|lp|Diablo 630 Line Printer:\ :lp=:rm=rose:rp=rattan:sd=/var/spool/lpd/rattan: # # bamboo is connected to rose as well: # bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :lp=:rm=rose:rp=bamboo:sd=/var/spool/lpd/bamboo: Then, we just need to make spooling directories on orchid: &prompt.root; mkdir -p /var/spool/lpd/rattan /var/spool/lpd/bamboo &prompt.root; chmod 770 /var/spool/lpd/rattan /var/spool/lpd/bamboo &prompt.root; chown daemon:daemon /var/spool/lpd/rattan /var/spool/lpd/bamboo Now, users on orchid can print to rattan and bamboo. If, for example, a user on orchid typed &prompt.user; lpr -P bamboo -d sushi-review.dvi the LPD system on orchid would copy the job to the spooling directory /var/spool/lpd/bamboo and note that it was a DVI job. As soon as the host rose has room in its bamboo spooling directory, the two LPDs would transfer the file to rose. The file would wait in rose's queue until it was finally printed. It would be converted from DVI to PostScript (since bamboo is a PostScript printer) on rose. Printers with Networked Data Stream Interfaces Often, when you buy a network interface card for a printer, you can get two versions: one which emulates a spooler (the more expensive version), or one which just lets you send data to it as if you were using a serial or parallel port (the cheaper version). This section tells how to use the cheaper version. For the more expensive one, see the previous section Printers Installed on Remote Hosts. The format of the /etc/printcap file lets you specify what serial or parallel interface to use, and (if you are using a serial interface), what baud rate, whether to use flow control, delays for tabs, conversion of newlines, and more. But there is no way to specify a connection to a printer that is listening on a TCP/IP or other network port. To send data to a networked printer, you need to develop a communications program that can be called by the text and conversion filters. Here is one such example: the script netprint takes all data on standard input and sends it to a network-attached printer. We specify the hostname of the printer as the first argument and the port number to which to connect as the second argument to netprint. Note that this supports one-way communication only (FreeBSD to printer); many network printers support two-way communication, and you might want to take advantage of that (to get printer status, perform accounting, etc.). #!/usr/bin/perl # # netprint - Text filter for printer attached to network # Installed in /usr/local/libexec/netprint # $#ARGV eq 1 || die "Usage: $0 <printer-hostname> <port-number>"; $printer_host = $ARGV[0]; $printer_port = $ARGV[1]; require 'sys/socket.ph'; ($ignore, $ignore, $protocol) = getprotobyname('tcp'); ($ignore, $ignore, $ignore, $ignore, $address) = gethostbyname($printer_host); $sockaddr = pack('S n a4 x8', &AF_INET, $printer_port, $address); socket(PRINTER, &PF_INET, &SOCK_STREAM, $protocol) || die "Can't create TCP/IP stream socket: $!"; connect(PRINTER, $sockaddr) || die "Can't contact $printer_host: $!"; while (<STDIN>) { print PRINTER; } exit 0; We can then use this script in various filters. Suppose we had a Diablo 750-N line printer connected to the network. The printer accepts data to print on port number 5100. The host name of the printer is scrivener. Here is the text filter for the printer: #!/bin/sh # # diablo-if-net - Text filter for Diablo printer `scrivener' listening # on port 5100. Installed in /usr/local/libexec/diablo-if-net # exec /usr/libexec/lpr/lpf "$@" | /usr/local/libexec/netprint scrivener 5100 Restricting Printer Usage printer restricting access to This section gives information on restricting printer usage. The LPD system lets you control who can access a printer, both locally or remotely, whether they can print multiple copies, how large their jobs can be, and how large the printer queues can get. Restricting Multiple Copies The LPD system makes it easy for users to print multiple copies of a file. Users can print jobs with lpr -#5 (for example) and get five copies of each file in the job. Whether this is a good thing is up to you. If you feel multiple copies cause unnecessary wear and tear on your printers, you can disable the option to &man.lpr.1; by adding the sc capability to the /etc/printcap file. When users submit jobs with the option, they will see: lpr: multiple copies are not allowed Note that if you have set up access to a printer remotely (see section Printers Installed on Remote Hosts), you need the sc capability on the remote /etc/printcap files as well, or else users will still be able to submit multiple-copy jobs by using another host. Here is an example. This is the /etc/printcap file for the host rose. The printer rattan is quite hearty, so we will allow multiple copies, but the laser printer bamboo is a bit more delicate, so we will disable multiple copies by adding the sc capability: # # /etc/printcap for host rose - restrict multiple copies on bamboo # rattan|line|diablo|lp|Diablo 630 Line Printer:\ :sh:sd=/var/spool/lpd/rattan:\ :lp=/dev/lpt0:\ :if=/usr/local/libexec/if-simple: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh:sd=/var/spool/lpd/bamboo:sc:\ :lp=/dev/ttyd5:fs#0x82000e1:xs#0x820:rw:\ :if=/usr/local/libexec/psif:\ :df=/usr/local/libexec/psdf: Now, we also need to add the sc capability on the host orchid's /etc/printcap (and while we are at it, let us disable multiple copies for the printer teak): # # /etc/printcap for host orchid - no multiple copies for local # printer teak or remote printer bamboo teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\ :lp=/dev/lpt0:sd=/var/spool/lpd/teak:mx#0:sc:\ :if=/usr/local/libexec/ifhp:\ :vf=/usr/local/libexec/vfhp:\ :of=/usr/local/libexec/ofhp: rattan|line|diablo|lp|Diablo 630 Line Printer:\ :lp=:rm=rose:rp=rattan:sd=/var/spool/lpd/rattan: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :lp=:rm=rose:rp=bamboo:sd=/var/spool/lpd/bamboo:sc: By using the sc capability, we prevent the use of lpr -#, but that still does not prevent users from running &man.lpr.1; multiple times, or from submitting the same file multiple times in one job like this: &prompt.user; lpr forsale.sign forsale.sign forsale.sign forsale.sign forsale.sign There are many ways to prevent this abuse (including ignoring it) which you are free to explore. Restricting Access To Printers You can control who can print to what printers by using the Unix group mechanism and the rg capability in /etc/printcap. Just place the users you want to have access to a printer in a certain group, and then name that group in the rg capability. Users outside the group (including root) will be greeted with lpr: Not a member of the restricted group if they try to print to the controlled printer. As with the sc (suppress multiple copies) capability, you need to specify rg on remote hosts that also have access to your printers, if you feel it is appropriate (see section Printers Installed on Remote Hosts). For example, we will let anyone access the printer rattan, but only those in group artists can use bamboo. Here is the familiar /etc/printcap for host rose: # # /etc/printcap for host rose - restricted group for bamboo # rattan|line|diablo|lp|Diablo 630 Line Printer:\ :sh:sd=/var/spool/lpd/rattan:\ :lp=/dev/lpt0:\ :if=/usr/local/libexec/if-simple: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh:sd=/var/spool/lpd/bamboo:sc:rg=artists:\ :lp=/dev/ttyd5:fs#0x82000e1:xs#0x820:rw:\ :if=/usr/local/libexec/psif:\ :df=/usr/local/libexec/psdf: Let us leave the other example /etc/printcap file (for the host orchid) alone. Of course, anyone on orchid can print to bamboo. It might be the case that we only allow certain logins on orchid anyway, and want them to have access to the printer. Or not. There can be only one restricted group per printer. Controlling Sizes of Jobs Submitted print jobs If you have many users accessing the printers, you probably need to put an upper limit on the sizes of the files users can submit to print. After all, there is only so much free space on the filesystem that houses the spooling directories, and you also need to make sure there is room for the jobs of other users. print jobs controlling LPD enables you to limit the maximum byte size a file in a job can be with the mx capability. The units are in BUFSIZ blocks, which are 1024 bytes. If you put a zero for this capability, there will be no limit on file size; however, if no mx capability is specified, then a default limit of 1000 blocks will be used. The limit applies to files in a job, and not the total job size. LPD will not refuse a file that is larger than the limit you place on a printer. Instead, it will queue as much of the file up to the limit, which will then get printed. The rest will be discarded. Whether this is correct behavior is up for debate. Let us add limits to our example printers rattan and bamboo. Since those artists' PostScript files tend to be large, we will limit them to five megabytes. We will put no limit on the plain text line printer: # # /etc/printcap for host rose # # # No limit on job size: # rattan|line|diablo|lp|Diablo 630 Line Printer:\ :sh:mx#0:sd=/var/spool/lpd/rattan:\ :lp=/dev/lpt0:\ :if=/usr/local/libexec/if-simple: # # Limit of five megabytes: # bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh:sd=/var/spool/lpd/bamboo:sc:rg=artists:mx#5000:\ :lp=/dev/ttyd5:fs#0x82000e1:xs#0x820:rw:\ :if=/usr/local/libexec/psif:\ :df=/usr/local/libexec/psdf: Again, the limits apply to the local users only. If you have set up access to your printers remotely, remote users will not get those limits. You will need to specify the mx capability in the remote /etc/printcap files as well. See section Printers Installed on Remote Hosts for more information on remote printing. There is another specialized way to limit job sizes from remote printers; see section Restricting Jobs from Remote Printers. Restricting Jobs from Remote Printers The LPD spooling system provides several ways to restrict print jobs submitted from remote hosts: Host restrictions You can control from which remote hosts a local LPD accepts requests with the files /etc/hosts.equiv and /etc/hosts.lpd. LPD checks to see if an incoming request is from a host listed in either one of these files. If not, LPD refuses the request. The format of these files is simple: one host name per line. Note that the file /etc/hosts.equiv is also used by the &man.ruserok.3; protocol, and affects programs like &man.rsh.1; and &man.rcp.1;, so be careful. For example, here is the /etc/hosts.lpd file on the host rose: orchid violet madrigal.fishbaum.de This means rose will accept requests from the hosts orchid, violet, and madrigal.fishbaum.de. If any other host tries to access rose's LPD, the job will be refused. Size restrictions You can control how much free space there needs to remain on the filesystem where a spooling directory resides. Make a file called minfree in the spooling directory for the local printer. Insert in that file a number representing how many disk blocks (512 bytes) of free space there has to be for a remote job to be accepted. This lets you insure that remote users will not fill your filesystem. You can also use it to give a certain priority to local users: they will be able to queue jobs long after the free disk space has fallen below the amount specified in the minfree file. For example, let us add a minfree file for the printer bamboo. We examine /etc/printcap to find the spooling directory for this printer; here is bamboo's entry: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh:sd=/var/spool/lpd/bamboo:sc:rg=artists:mx#5000:\ :lp=/dev/ttyd5:fs#0x82000e1:xs#0x820:rw:mx#5000:\ :if=/usr/local/libexec/psif:\ :df=/usr/local/libexec/psdf: The spooling directory is given in the sd capability. We will make three megabytes (which is 6144 disk blocks) the amount of free disk space that must exist on the filesystem for LPD to accept remote jobs: &prompt.root; echo 6144 > /var/spool/lpd/bamboo/minfree User restrictions You can control which remote users can print to local printers by specifying the rs capability in /etc/printcap. When rs appears in the entry for a locally-attached printer, LPD will accept jobs from remote hosts if the user submitting the job also has an account of the same login name on the local host. Otherwise, LPD refuses the job. This capability is particularly useful in an environment where there are (for example) different departments sharing a network, and some users transcend departmental boundaries. By giving them accounts on your systems, they can use your printers from their own departmental systems. If you would rather allow them to use only your printers and not your computer resources, you can give them token accounts, with no home directory and a useless shell like /usr/bin/false. Accounting for Printer Usage accounting printer So, you need to charge for printouts. And why not? Paper and ink cost money. And then there are maintenance costs—printers are loaded with moving parts and tend to break down. You have examined your printers, usage patterns, and maintenance fees and have come up with a per-page (or per-foot, per-meter, or per-whatever) cost. Now, how do you actually start accounting for printouts? Well, the bad news is the LPD spooling system does not provide much help in this department. Accounting is highly dependent on the kind of printer in use, the formats being printed, and your requirements in charging for printer usage. To implement accounting, you have to modify a printer's text filter (to charge for plain text jobs) and the conversion filters (to charge for other file formats), to count pages or query the printer for pages printed. You cannot get away with using the simple output filter, since it cannot do accounting. See section Filters. Generally, there are two ways to do accounting: Periodic accounting is the more common way, possibly because it is easier. Whenever someone prints a job, the filter logs the user, host, and number of pages to an accounting file. Every month, semester, year, or whatever time period you prefer, you collect the accounting files for the various printers, tally up the pages printed by users, and charge for usage. Then you truncate all the logging files, starting with a clean slate for the next period. Timely accounting is less common, probably because it is more difficult. This method has the filters charge users for printouts as soon as they use the printers. Like disk quotas, the accounting is immediate. You can prevent users from printing when their account goes in the red, and might provide a way for users to check and adjust their print quotas. But this method requires some database code to track users and their quotas. The LPD spooling system supports both methods easily: since you have to provide the filters (well, most of the time), you also have to provide the accounting code. But there is a bright side: you have enormous flexibility in your accounting methods. For example, you choose whether to use periodic or timely accounting. You choose what information to log: user names, host names, job types, pages printed, square footage of paper used, how long the job took to print, and so forth. And you do so by modifying the filters to save this information. Quick and Dirty Printer Accounting FreeBSD comes with two programs that can get you set up with simple periodic accounting right away. They are the text filter lpf, described in section lpf: a Text Filter, and &man.pac.8;, a program to gather and total entries from printer accounting files. As mentioned in the section on filters (Filters), LPD starts the text and the conversion filters with the name of the accounting file to use on the filter command line. The filters can use this argument to know where to write an accounting file entry. The name of this file comes from the af capability in /etc/printcap, and if not specified as an absolute path, is relative to the spooling directory. LPD starts lpf with page width and length arguments (from the pw and pl capabilities). lpf uses these arguments to determine how much paper will be used. After sending the file to the printer, it then writes an accounting entry in the accounting file. The entries look like this: 2.00 rose:andy 3.00 rose:kelly 3.00 orchid:mary 5.00 orchid:mary 2.00 orchid:zhang You should use a separate accounting file for each printer, as lpf has no file locking logic built into it, and two lpfs might corrupt each other's entries if they were to write to the same file at the same time. An easy way to insure a separate accounting file for each printer is to use af=acct in /etc/printcap. Then, each accounting file will be in the spooling directory for a printer, in a file named acct. When you are ready to charge users for printouts, run the &man.pac.8; program. Just change to the spooling directory for the printer you want to collect on and type pac. You will get a dollar-centric summary like the following: Login pages/feet runs price orchid:kelly 5.00 1 $ 0.10 orchid:mary 31.00 3 $ 0.62 orchid:zhang 9.00 1 $ 0.18 rose:andy 2.00 1 $ 0.04 rose:kelly 177.00 104 $ 3.54 rose:mary 87.00 32 $ 1.74 rose:root 26.00 12 $ 0.52 total 337.00 154 $ 6.74 These are the arguments &man.pac.8; expects: Which printer to summarize. This option works only if there is an absolute path in the af capability in /etc/printcap. Sort the output by cost instead of alphabetically by user name. Ignore host name in the accounting files. With this option, user smith on host alpha is the same user smith on host gamma. Without, they are different users. Compute charges with price dollars per page or per foot instead of the price from the pc capability in /etc/printcap, or two cents (the default). You can specify price as a floating point number. Reverse the sort order. Make an accounting summary file and truncate the accounting file. name Print accounting information for the given user names only. In the default summary that &man.pac.8; produces, you see the number of pages printed by each user from various hosts. If, at your site, host does not matter (because users can use any host), run pac -m, to produce the following summary: Login pages/feet runs price andy 2.00 1 $ 0.04 kelly 182.00 105 $ 3.64 mary 118.00 35 $ 2.36 root 26.00 12 $ 0.52 zhang 9.00 1 $ 0.18 total 337.00 154 $ 6.74 To compute the dollar amount due, &man.pac.8; uses the pc capability in the /etc/printcap file (default of 200, or 2 cents per page). Specify, in hundredths of cents, the price per page or per foot you want to charge for printouts in this capability. You can override this value when you run &man.pac.8; with the option. The units for the option are in dollars, though, not hundredths of cents. For example, &prompt.root; pac -p1.50 makes each page cost one dollar and fifty cents. You can really rake in the profits by using this option. Finally, running pac -s will save the summary information in a summary accounting file, which is named the same as the printer's accounting file, but with _sum appended to the name. It then truncates the accounting file. When you run &man.pac.8; again, it rereads the summary file to get starting totals, then adds information from the regular accounting file. How Can You Count Pages Printed? In order to perform even remotely accurate accounting, you need to be able to determine how much paper a job uses. This is the essential problem of printer accounting. For plain text jobs, the problem is not that hard to solve: you count how many lines are in a job and compare it to how many lines per page your printer supports. Do not forget to take into account backspaces in the file which overprint lines, or long logical lines that wrap onto one or more additional physical lines. The text filter lpf (introduced in lpf: a Text Filter) takes into account these things when it does accounting. If you are writing a text filter which needs to do accounting, you might want to examine lpf's source code. How do you handle other file formats, though? Well, for DVI-to-LaserJet or DVI-to-PostScript conversion, you can have your filter parse the diagnostic output of dvilj or dvips and look to see how many pages were converted. You might be able to do similar things with other file formats and conversion programs. But these methods suffer from the fact that the printer may not actually print all those pages. For example, it could jam, run out of toner, or explode—and the user would still get charged. So, what can you do? There is only one sure way to do accurate accounting. Get a printer that can tell you how much paper it uses, and attach it via a serial line or a network connection. Nearly all PostScript printers support this notion. Other makes and models do as well (networked Imagen laser printers, for example). Modify the filters for these printers to get the page usage after they print each job and have them log accounting information based on that value only. There is no line counting nor error-prone file examination required. Of course, you can always be generous and make all printouts free. Using Printers printer usage This section tells you how to use printers you have setup with FreeBSD. Here is an overview of the user-level commands: &man.lpr.1; Print jobs &man.lpq.1; Check printer queues &man.lprm.1; Remove jobs from a printer's queue There is also an administrative command, &man.lpc.8;, described in the section Administrating the LPD Spooler, used to control printers and their queues. All three of the commands &man.lpr.1;, &man.lprm.1;, and &man.lpq.1; accept an option to specify on which printer/queue to operate, as listed in the /etc/printcap file. This enables you to submit, remove, and check on jobs for various printers. If you do not use the option, then these commands use the printer specified in the PRINTER environment variable. Finally, if you do not have a PRINTER environment variable, these commands default to the printer named lp. Hereafter, the terminology default printer means the printer named in the PRINTER environment variable, or the printer named lp when there is no PRINTER environment variable. Printing Jobs To print files, type: &prompt.user; lpr filename ... printing This prints each of the listed files to the default printer. If you list no files, &man.lpr.1; reads data to print from standard input. For example, this command prints some important system files: &prompt.user; lpr /etc/host.conf /etc/hosts.equiv To select a specific printer, type: &prompt.user; lpr -P printer-name filename ... This example prints a long listing of the current directory to the printer named rattan: &prompt.user; ls -l | lpr -P rattan Because no files were listed for the &man.lpr.1; command, lpr read the data to print from standard input, which was the output of the ls -l command. The &man.lpr.1; command can also accept a wide variety of options to control formatting, apply file conversions, generate multiple copies, and so forth. For more information, see the section Printing Options. Checking Jobs print jobs When you print with &man.lpr.1;, the data you wish to print is put together in a package called a print job, which is sent to the LPD spooling system. Each printer has a queue of jobs, and your job waits in that queue along with other jobs from yourself and from other users. The printer prints those jobs in a first-come, first-served order. To display the queue for the default printer, type &man.lpq.1;. For a specific printer, use the option. For example, the command &prompt.user; lpq -P bamboo shows the queue for the printer named bamboo. Here is an example of the output of the lpq command: bamboo is ready and printing Rank Owner Job Files Total Size active kelly 9 /etc/host.conf, /etc/hosts.equiv 88 bytes 2nd kelly 10 (standard input) 1635 bytes 3rd mary 11 ... 78519 bytes This shows three jobs in the queue for bamboo. The first job, submitted by user kelly, got assigned job number 9. Every job for a printer gets a unique job number. Most of the time you can ignore the job number, but you will need it if you want to cancel the job; see section Removing Jobs for details. Job number nine consists of two files; multiple files given on the &man.lpr.1; command line are treated as part of a single job. It is the currently active job (note the word active under the Rank column), which means the printer should be currently printing that job. The second job consists of data passed as the standard input to the &man.lpr.1; command. The third job came from user mary; it is a much larger job. The pathname of the file she is trying to print is too long to fit, so the &man.lpq.1; command just shows three dots. The very first line of the output from &man.lpq.1; is also useful: it tells what the printer is currently doing (or at least what LPD thinks the printer is doing). The &man.lpq.1; command also support a option to generate a detailed long listing. Here is an example of lpq -l: waiting for bamboo to become ready (offline ?) kelly: 1st [job 009rose] /etc/host.conf 73 bytes /etc/hosts.equiv 15 bytes kelly: 2nd [job 010rose] (standard input) 1635 bytes mary: 3rd [job 011rose] /home/orchid/mary/research/venus/alpha-regio/mapping 78519 bytes Removing Jobs If you change your mind about printing a job, you can remove the job from the queue with the &man.lprm.1; command. Often, you can even use &man.lprm.1; to remove an active job, but some or all of the job might still get printed. To remove a job from the default printer, first use &man.lpq.1; to find the job number. Then type: &prompt.user; lprm job-number To remove the job from a specific printer, add the option. The following command removes job number 10 from the queue for the printer bamboo: &prompt.user; lprm -P bamboo 10 The &man.lprm.1; command has a few shortcuts: lprm - Removes all jobs (for the default printer) belonging to you. lprm user Removes all jobs (for the default printer) belonging to user. The superuser can remove other users' jobs; you can remove only your own jobs. lprm With no job number, user name, or appearing on the command line, &man.lprm.1; removes the currently active job on the default printer, if it belongs to you. The superuser can remove any active job. Just use the option with the above shortcuts to operate on a specific printer instead of the default. For example, the following command removes all jobs for the current user in the queue for the printer named rattan: &prompt.user; lprm -P rattan - If you are working in a networked environment, &man.lprm.1; will let you remove jobs only from the host from which the jobs were submitted, even if the same printer is available from other hosts. The following command sequence demonstrates this: &prompt.user; lpr -P rattan myfile &prompt.user; rlogin orchid &prompt.user; lpq -P rattan Rank Owner Job Files Total Size active seeyan 12 ... 49123 bytes 2nd kelly 13 myfile 12 bytes &prompt.user; lprm -P rattan 13 rose: Permission denied &prompt.user; logout &prompt.user; lprm -P rattan 13 dfA013rose dequeued cfA013rose dequeued Beyond Plain Text: Printing Options The &man.lpr.1; command supports a number of options that control formatting text, converting graphic and other file formats, producing multiple copies, handling of the job, and more. This section describes the options. Formatting and Conversion Options The following &man.lpr.1; options control formatting of the files in the job. Use these options if the job does not contain plain text or if you want plain text formatted through the &man.pr.1; utility. TeX For example, the following command prints a DVI file (from the TeX typesetting system) named fish-report.dvi to the printer named bamboo: &prompt.user; lpr -P bamboo -d fish-report.dvi These options apply to every file in the job, so you cannot mix (say) DVI and ditroff files together in a job. Instead, submit the files as separate jobs, using a different conversion option for each job. All of these options except and require conversion filters installed for the destination printer. For example, the option requires the DVI conversion filter. Section Conversion Filters gives details. Print cifplot files. Print DVI files. Print FORTRAN text files. Print plot data. Indent the output by number columns; if you omit number, indent by 8 columns. This option works only with certain conversion filters. Do not put any space between the and the number. Print literal text data, including control characters. Print ditroff (device independent troff) data. -p Format plain text with &man.pr.1; before printing. See &man.pr.1; for more information. Use title on the &man.pr.1; header instead of the file name. This option has effect only when used with the option. Print troff data. Print raster data. Here is an example: this command prints a nicely formatted version of the &man.ls.1; manual page on the default printer: &prompt.user; zcat /usr/share/man/man1/ls.1.gz | troff -t -man | lpr -t The &man.zcat.1; command uncompresses the source of the &man.ls.1; manual page and passes it to the &man.troff.1; command, which formats that source and makes GNU troff output and passes it to &man.lpr.1;, which submits the job to the LPD spooler. Because we used the option to &man.lpr.1;, the spooler will convert the GNU troff output into a format the default printer can understand when it prints the job. Job Handling Options The following options to &man.lpr.1; tell LPD to handle the job specially: -# copies Produce a number of copies of each file in the job instead of just one copy. An administrator may disable this option to reduce printer wear-and-tear and encourage photocopier usage. See section Restricting Multiple Copies. This example prints three copies of parser.c followed by three copies of parser.h to the default printer: &prompt.user; lpr -#3 parser.c parser.h -m Send mail after completing the print job. With this option, the LPD system will send mail to your account when it finishes handling your job. In its message, it will tell you if the job completed successfully or if there was an error, and (often) what the error was. -s Do not copy the files to the spooling directory, but make symbolic links to them instead. If you are printing a large job, you probably want to use this option. It saves space in the spooling directory (your job might overflow the free space on the filesystem where the spooling directory resides). It saves time as well since LPD will not have to copy each and every byte of your job to the spooling directory. There is a drawback, though: since LPD will refer to the original files directly, you cannot modify or remove them until they have been printed. If you are printing to a remote printer, LPD will eventually have to copy files from the local host to the remote host, so the option will save space only on the local spooling directory, not the remote. It is still useful, though. -r Remove the files in the job after copying them to the spooling directory, or after printing them with the option. Be careful with this option! Header Page Options These options to &man.lpr.1; adjust the text that normally appears on a job's header page. If header pages are suppressed for the destination printer, these options have no effect. See section Header Pages for information about setting up header pages. -C text Replace the hostname on the header page with text. The hostname is normally the name of the host from which the job was submitted. -J text Replace the job name on the header page with text. The job name is normally the name of the first file of the job, or stdin if you are printing standard input. -h Do not print any header page. At some sites, this option may have no effect due to the way header pages are generated. See Header Pages for details. Administrating Printers As an administrator for your printers, you have had to install, set up, and test them. Using the &man.lpc.8; command, you can interact with your printers in yet more ways. With &man.lpc.8;, you can Start and stop the printers Enable and disable their queues Rearrange the order of the jobs in each queue. First, a note about terminology: if a printer is stopped, it will not print anything in its queue. Users can still submit jobs, which will wait in the queue until the printer is started or the queue is cleared. If a queue is disabled, no user (except root) can submit jobs for the printer. An enabled queue allows jobs to be submitted. A printer can be started for a disabled queue, in which case it will continue to print jobs in the queue until the queue is empty. In general, you have to have root privileges to use the &man.lpc.8; command. Ordinary users can use the &man.lpc.8; command to get printer status and to restart a hung printer only. Here is a summary of the &man.lpc.8; commands. Most of the commands take a printer-name argument to tell on which printer to operate. You can use all for the printer-name to mean all printers listed in /etc/printcap. abort printer-name Cancel the current job and stop the printer. Users can still submit jobs if the queue is enabled. clean printer-name Remove old files from the printer's spooling directory. Occasionally, the files that make up a job are not properly removed by LPD, particularly if there have been errors during printing or a lot of administrative activity. This command finds files that do not belong in the spooling directory and removes them. disable printer-name Disable queuing of new jobs. If the printer is running, it will continue to print any jobs remaining in the queue. The superuser (root) can always submit jobs, even to a disabled queue. This command is useful while you are testing a new printer or filter installation: disable the queue and submit jobs as root. Other users will not be able to submit jobs until you complete your testing and re-enable the queue with the enable command. down printer-name message Take a printer down. Equivalent to disable followed by stop. The message appears as the printer's status whenever a user checks the printer's queue with &man.lpq.1; or status with lpc status. enable printer-name Enable the queue for a printer. Users can submit jobs but the printer will not print anything until it is started. help command-name Print help on the command command-name. With no command-name, print a summary of the commands available. restart printer-name Start the printer. Ordinary users can use this command if some extraordinary circumstance hangs LPD, but they cannot start a printer stopped with either the stop or down commands. The restart command is equivalent to abort followed by start. start printer-name Start the printer. The printer will print jobs in its queue. stop printer-name Stop the printer. The printer will finish the current job and will not print anything else in its queue. Even though the printer is stopped, users can still submit jobs to an enabled queue. topq printer-name job-or-username Rearrange the queue for printer-name by placing the jobs with the listed job numbers or the jobs belonging to username at the top of the queue. For this command, you cannot use all as the printer-name. up printer-name Bring a printer up; the opposite of the down command. Equivalent to start followed by enable. &man.lpc.8; accepts the above commands on the command line. If you do not enter any commands, &man.lpc.8; enters an interactive mode, where you can enter commands until you type exit, quit, or end-of-file. Alternatives to the Standard Spooler If you have been reading straight through this manual, by now you have learned just about everything there is to know about the LPD spooling system that comes with FreeBSD. You can probably appreciate many of its shortcomings, which naturally leads to the question: What other spooling systems are out there (and work with FreeBSD)? LPRng LPRng LPRng, which purportedly means LPR: the Next Generation is a complete rewrite of PLP. Patrick Powell and Justin Mason (the principal maintainer of PLP) collaborated to make LPRng. The main site for LPRng is http://www.astart.com/lprng/LPRng.html. Troubleshooting After performing the simple test with &man.lptest.1;, you might have gotten one of the following results instead of the correct printout: It worked, after awhile; or, it did not eject a full sheet. The printer printed the above, but it sat for awhile and did nothing. In fact, you might have needed to press a PRINT REMAINING or FORM FEED button on the printer to get any results to appear. If this is the case, the printer was probably waiting to see if there was any more data for your job before it printed anything. To fix this problem, you can have the text filter send a FORM FEED character (or whatever is necessary) to the printer. This is usually sufficient to have the printer immediately print any text remaining in its internal buffer. It is also useful to make sure each print job ends on a full sheet, so the next job does not start somewhere on the middle of the last page of the previous job. The following replacement for the shell script /usr/local/libexec/if-simple prints a form feed after it sends the job to the printer: #!/bin/sh # # if-simple - Simple text input filter for lpd # Installed in /usr/local/libexec/if-simple # # Simply copies stdin to stdout. Ignores all filter arguments. # Writes a form feed character (\f) after printing job. /bin/cat && printf "\f" && exit 0 exit 2 It produced the staircase effect. You got the following on paper: !"#$%&'()*+,-./01234 "#$%&'()*+,-./012345 #$%&'()*+,-./0123456 MS-DOS OS/2 ASCII You have become another victim of the staircase effect, caused by conflicting interpretations of what characters should indicate a new line. Unix-style operating systems use a single character: ASCII code 10, the line feed (LF). MS-DOS, OS/2, and others uses a pair of characters, ASCII code 10 and ASCII code 13 (the carriage return or CR). Many printers use the MS-DOS convention for representing new-lines. When you print with FreeBSD, your text used just the line feed character. The printer, upon seeing a line feed character, advanced the paper one line, but maintained the same horizontal position on the page for the next character to print. That is what the carriage return is for: to move the location of the next character to print to the left edge of the paper. Here is what FreeBSD wants your printer to do: Printer received CR Printer prints CR Printer received LF Printer prints CR + LF Here are some ways to achieve this: Use the printer's configuration switches or control panel to alter its interpretation of these characters. Check your printer's manual to find out how to do this. If you boot your system into other operating systems besides FreeBSD, you may have to reconfigure the printer to use a an interpretation for CR and LF characters that those other operating systems use. You might prefer one of the other solutions, below. Have FreeBSD's serial line driver automatically convert LF to CR+LF. Of course, this works with printers on serial ports only. To enable this feature, set the CRMOD bit in fs capability in the /etc/printcap file for the printer. Send an escape code to the printer to have it temporarily treat LF characters differently. Consult your printer's manual for escape codes that your printer might support. When you find the proper escape code, modify the text filter to send the code first, then send the print job. PCL Here is an example text filter for printers that understand the Hewlett-Packard PCL escape codes. This filter makes the printer treat LF characters as a LF and CR; then it sends the job; then it sends a form feed to eject the last page of the job. It should work with nearly all Hewlett Packard printers. #!/bin/sh # # hpif - Simple text input filter for lpd for HP-PCL based printers # Installed in /usr/local/libexec/hpif # # Simply copies stdin to stdout. Ignores all filter arguments. # Tells printer to treat LF as CR+LF. Ejects the page when done. printf "\033&k2G" && cat && printf "\033&l0H" && exit 0 exit 2 Here is an example /etc/printcap from a host called orchid. It has a single printer attached to its first parallel port, a Hewlett Packard LaserJet 3Si named teak. It is using the above script as its text filter: # # /etc/printcap for host orchid # teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\ :lp=/dev/lpt0:sh:sd=/var/spool/lpd/teak:mx#0:\ :if=/usr/local/libexec/hpif: It overprinted each line. The printer never advanced a line. All of the lines of text were printed on top of each other on one line. This problem is the opposite of the staircase effect, described above, and is much rarer. Somewhere, the LF characters that FreeBSD uses to end a line are being treated as CR characters to return the print location to the left edge of the paper, but not also down a line. Use the printer's configuration switches or control panel to enforce the following interpretation of LF and CR characters: Printer receives Printer prints CR CR LF CR + LF The printer lost characters. While printing, the printer did not print a few characters in each line. The problem might have gotten worse as the printer ran, losing more and more characters. The problem is that the printer cannot keep up with the speed at which the computer sends data over a serial line (this problem should not occur with printers on parallel ports). There are two ways to overcome the problem: If the printer supports XON/XOFF flow control, have FreeBSD use it by specifying the TANDEM bit in the fs capability. If the printer supports carrier flow control, specify the MDMBUF bit in the fs capability. Make sure the cable connecting the printer to the computer is correctly wired for carrier flow control. If the printer does not support any flow control, use some combination of the NLDELAY, TBDELAY, CRDELAY, VTDELAY, and BSDELAY bits in the fs capability to add appropriate delays to the stream of data sent to the printer. It printed garbage. The printer printed what appeared to be random garbage, but not the desired text. This is usually another symptom of incorrect communications parameters with a serial printer. Double-check the bps rate in the br capability, and the parity bits in the fs and fc capabilities; make sure the printer is using the same settings as specified in the /etc/printcap file. Nothing happened. If nothing happened, the problem is probably within FreeBSD and not the hardware. Add the log file (lf) capability to the entry for the printer you are debugging in the /etc/printcap file. For example, here is the entry for rattan, with the lf capability: rattan|line|diablo|lp|Diablo 630 Line Printer:\ :sh:sd=/var/spool/lpd/rattan:\ :lp=/dev/lpt0:\ :if=/usr/local/libexec/if-simple:\ :lf=/var/log/rattan.log Then, try printing again. Check the log file (in our example, /var/log/rattan.log) to see any error messages that might appear. Based on the messages you see, try to correct the problem. If you do not specify a lf capability, LPD uses /dev/console as a default.