The BSD UNIX kernel is a C program compiled and installed by make . The config command reads the kernel configuration file and generates the files (including the Makefile) needed to compile and link the kernel. On FreeBSD systems, the kernel configuration file is located in the directory /usr/src/sys/i386/conf . 
A large kernel configuration file named GENERIC is delivered with the FreeBSD system. The GENERIC kernel file configures all of the standard devices for your system - including everything necessary for TCP/IP. No modifications are necessary for the GENERIC kernel to run basic TCP/IP services. The reasons for modifying the BSD kernel are the same as those discussed for the Linux kernel: to make a smaller, more efficient kernel, or to add new features.
There is no standard name for a BSD kernel configuration file. When you create a configuration file, choose any name you wish. By convention, BSD kernel configuration filenames use uppercase letters. To create a new configuration, copy GENERIC to the new file and then edit the newly created file. The following creates a new configuration file called FILBERT :
# cd /usr/src/sys/i386/conf # cp GENERIC FILBERT
If the kernel has been modified on your system, the system administrator will have created a new configuration file in the /usr/src/sys/i386/conf directory. The kernel configuration file contains many configuration commands that cover all aspects of the system configuration. This text discusses only those parameters that directly affect TCP/IP configuration. See the documentation that comes with the FreeBSD system for information about the other configuration commands.
For a network administrator, it is more important to understand which kernel statements are necessary to configure TCP/IP than to understand the detailed structure of each statement. Three types of statements are used to configure TCP/IP in the BSD kernel: options, pseudo-device, and device statements.
options INET # basic networking support--mandatory
Every BSD-based system running TCP/IP has an options INET statement in its kernel configuration file. The statement produces a -DINET argument for the C complier, which in turn causes the IP, ICMP, TCP, UDP, and ARP modules to be compiled into the kernel. This single statement incorporates the basic transport and IP datagram services into the system. Never remove this statement from the configuration file.
There are several other options statements in addition to the required INET option. Some of these perform functions identical to features we have already seen in the Linux configuration. A few have no direct parallels in the Linux configuration.
options GATEWAY # internetwork gateway
The GATEWAY option determines whether the system forwards IP datagrams destined for another computer. When this option is selected, the system forwards datagrams if it has more than one network interface; i.e., the system is assumed to be a gateway. You don't need GATEWAY on a system with a single network interface. Hosts - systems with one network interface - do not forward the packets of other systems, because this would hide configuration problems on other systems on the network. If the other systems are incorrectly delivering datagrams to a host, forwarding the datagrams makes it appear as if they were correctly addressed and makes it difficult to detect the real problem. On occasion, you might even want to force a system that has multiple network interfaces not to forward datagrams by commenting options GATEWAY out of your configuration. This is useful for preventing a multi-homed host (a host with two network interfaces) from acting as a gateway.
options IPFIREWALL # firewall
The IPFIREWALL option prepares the system to act as a firewall. The full firewall implementation requires application software and other tools. However, certain functions of a firewall, such as address filtering, must be implemented in the kernel. This option requests those kernel-level services. A variant of this option is IPFIREWALL_VERBOSE, which enables the same basic kernel services with enhanced error reporting. The enhanced errors can be useful for detecting intrusions, but they increase the size of the kernel.
options MROUTING # Multicast routing
The MROUTING option adds multicast routing support to the kernel. A multicast kernel is necessary for the system to be able to interpret multicast addresses and for the system to support multicast applications like MBONE and Internet Talk Radio.
options IPACCT # ipaccounting
The IPACCT option adds additional code and counters that keep track of network usage, which is helpful for billing purposes.
options ARP_PROXYALL # global proxy ARP
The ARP_PROXYALL option turns the system into a proxy ARP server. The Address Resolution Protocol (ARP) is discussed in Chapter 2, Delivering the Data . Proxy ARP is a variant on the standard protocol in which a server answers the ARP request for its clients. Here's how it works. Host A sends out an ARP request for the Ethernet address of host B. The proxy ARP server, C, hears the request and sends an ARP response back to A claiming that C's Ethernet address is the address of host B. A then sends traffic intended for B to C because it uses C's Ethernet address. C is therefore responsible for forwarding the traffic on to B. The proxy ARP server is usually a router and proxy ARP is used as a means of forwarding traffic between systems that cannot use normal routing for that traffic.
In Chapter 2 , we saw how a system can act as a proxy ARP server for individual addresses using the publish option on the arp command. The ARP_PROXYALL kernel option creates a server for all addresses; not just for individual addresses configured in the ARP table.
options "TCP_COMPAT_42" # emulate 4.2BSD TCP bugs
This option prevents connections between 4.2 and FreeBSD systems from hanging by adjusting FreeBSD to ignore mistakes made by 4.2. This parameter also disables UDP checksum calculations. The UDP checksum calculation in BSD 4.2 was incorrect, so when a host receives a UDP packet from a system running 4.2, it causes a checksum error. This parameter tells the system to ignore these errors. In addition, setting this parameter prevents the system from sending TCP Sequence Numbers that are interpreted as negative numbers by 4.2 systems. With this option, the initial sequence number will be set to zero for each connection. Forcing sequence numbers to zero is a potential security problem because it allows an intruder to guess the sequence number and to interject bogus packets into a TCP stream. For this reason, avoid using this parameter unless you must.
The second statement required by TCP/IP in all BSD configurations is a pseudo-device statement. A pseudo-device is a device driver not directly associated with an actual piece of hardware. The pseudo-device statement creates a header ( .h ) file that is identified by the pseudo-device name in the kernel directory. For example, the statement shown below creates the file loop.h :
pseudo-device loop # loopback network--mandatory
The loop pseudo-device is necessary to create the loopback device (lo0). This device is associated with the loopback address 127.0.0.1; it is defined as a pseudo-device because it is not really a piece of hardware.
Another pseudo-device that is used on many FreeBSD TCP/IP systems is:
pseudo-device ether # basic Ethernet support
This statement is necessary to support Ethernet. The ether pseudo-device is required for full support of ARP and other Ethernet specific functions. While it is possible that a system that does not have Ethernet may not require this statement, it is usually configured, and should remain in your kernel configuration.
pseudo-device pty 16 # pseudo-tty's
This statement defines the virtual terminal devices used by remote login services such as rlogin and telnet . Pseudo-terminals are also used by many other applications, such as Emacs, that have no direct connection to TCP/IP networking. The number, 16 in the example, is the number of ptys created by the kernel. The maximum on a FreeBSD system is 64.
pseudo-device sl 2 # Serial Line IP
This statement defines the interface for the Serial Line IP protocol. The number, 2 in the example, defines the number of SLIP pseudo-devices created by the kernel. The two devices created here would be addressed as device sl0 and sl1.
pseudo-device ppp 2 # Point-to-point protocol
The ppp pseudo-device is the interface for the Point-to-Point Protocol. The number, 2 in the example, defines the number of PPP pseudo-devices created by the kernel. The two devices created here would be addressed as device ppp0 and ppp1. Two other pseudo-devices directly related to PPP are shown next.
pseudo-device sppp # Generic synchronous PPP pseudo-device tun 1 # Tunnel driver(user process ppp)
The sppp statement adds support for synchronous PPP data link-layer protocols. Normally, PPP runs over a dial-up line using an asynchronous link protocol. Asynchronous modems are the common modems all of us have on our home computers. Synchronous modems and synchronous link protocols are used on leased lines.
The tun pseudo-device is a tunnel driver used by user-level PPP software. Tunneling is when a system passes one protocol through another protocol; tun is a FreeBSD feature for doing this over PPP links. The number, 1 in the example, is the number of tunnels that will be supported by this kernel.
The last three pseudo-devices are less frequently used.
pseudo-device fddi # Generic FDDI pseudo-device bpfilter 4 # Berkeley packet filter pseudo-device disc # Discard device
The bpfilter statement adds the support necessary for capturing packets. Capturing packets is an essential part of protocol analyzers; see Chapter 11, Troubleshooting TCP/IP . When the bpfilter statement is included in the BSD kernel, the Ethernet interface can be placed into "promiscuous mode".  An interface in promiscuous mode passes all packets, not just those addressed to the local system, up to the software at the next layer. This feature is useful for a system administrator troubleshooting a network. But it can also be used by intruders to steal passwords and compromise security. Use the bpfilter pseudo-device only if you really need it. The number, 4 in the example, indicates the maximum number of Ethernet interfaces that can be monitored by bpfilter.
Real hardware devices are defined using the device statement. Every host attached to a TCP/IP network requires some physical hardware for that attachment. The hardware is declared with a device statement in the kernel configuration file. There are many possible network interfaces for TCP/IP, but the most common are Ethernet interfaces.
Table 5.1 lists the Ethernet device drivers available with FreeeBSD 2.1.5.
A sample device statement shows the general format of the commands used to configure an Ethernet interface in the FreeBSD kernel:
device ed0 at isa? port 0x280 net irq 5 iomem 0xd8000 vector edintr device de0
Note that the ed0 device statement defines the bus type (isa), the I/O base address (port 0x280), the interrupt number (irq 5) and the memory address (iomem 0xd8000). These values should match the values configured on the adapter card. All of these are standard items for configuring PC hardware.  On the other hand, the de0 device statement requires very little configuration because it configures a card attached to the PCI bus. The PCI is an intelligent bus that can determine the configuration directly from the hardware.
Ethernet is not the only TCP/IP network interface supported by FreeBSD. It supports an experimental ISDN interface as well as the DEC FDDI adapter. More widely used than these are the serial line interfaces necessary for SLIP and PPP.
device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr device sio1 at isa? port "IO_COM2" tty irq 3 vector siointr device sio2 at isa? port "IO_COM3" tty irq 5 vector siointr device sio3 at isa? port "IO_COM4" tty irq 9 vector siointr
The four serial interfaces, sio0 through sio3, correspond to the MS-DOS interfaces COM1 to COM4. These are needed for SLIP and PPP. Chapter 6 covers other aspects of configuring PPP and SLIP.
The device statement varies according to the interface being configured. But how do you know which hardware interfaces are installed in your system? Remember that the GENERIC kernel that comes with your FreeBSD system is configured for a large number of devices. A simple way to tell which hardware interfaces are installed in your system is to look at the messages displayed on the console at boot time. These messages show all of the devices, including network devices, that the kernel found during initialization. Look at the output of the dmesg command. It displays a copy of the console messages generated during the last boot.
The options, pseudo-device, and device statements found in the kernel configuration file tell the system to include the TCP/IP hardware and software in the kernel. The statements in your configuration may vary somewhat from those shown in the previous examples. But you have the same basic statements in your kernel configuration file. With these basic statements, FreeBSD UNIX is ready to run TCP/IP.