For information on editing, see the description of Plan 9 wiki syntax.
The first section of this page describes the simplest possible setup for a standalone terminal, the rest of the page describes how to setup more complex Plan 9 network. STANDALONE TERMINAL NETWORK SETUP To configure your network connection on a standalone terminal you only need to call ipconfig(8) and run ndb/dns -r. If you have DHCP just run: ! ip/ipconfig Or to explicitly set the configuration: ! ip/ipconfig -g ether /net/ether0 After calling ipconfig make sure to run ndb/dns -r to enable dns resolution. To make this configuration permanent edit your /rc/bin/termrc commenting out and editing(if needed) the corresponding lines that call ipconfig(8). You can use ip/ping to test that your network connection is working properly. If you have problems see the "troubleshooting" section below. NETWORK DATABASE Plan 9 uses a single database for storing all the network-related configuration information in the system. The database stores the configuration for machines specifically identifiable by the local installation, default configurations for machines in particular subnets, domain name resolution information, and mappings between TCP service names and port numbers among other things. The database is assembled from a number of text files bearing a particular record structure. The default root of the database is the text file /lib/ndb/local. The most important entry in that file is the ``database='' entry, which specifies a list of other files to include. For example, ! database= ! file=/lib/ndb/local ! file=/lib/ndb/local-cs ! file=/lib/ndb/common It is from the contents of this file and those in the list that the database is assembled. These files are typically used by ndb/cs commands in the startup scripts(e.g. /rc/bin/cpurc). Conventionally, the file /lib/ndb/common is for standard port definitions and the like; the other files hold actual system configuration. RECORD STRUCTURE Lexically, a record is an unindented line followed by a series of indented lines. Thus an unindented line, a blank line, or a comment line (one beginning with #) ends a record. Semantically, a record is a series of ``key=value'' tuples. Tuples on the same line bind slightly more tightly than tuples on different lines, but usually that's not important. An example record is: ! ip=10.247.62.235 ip=10.247.60.200 sys=lusitania ether=0060088bc416 ! proto=il ! dom=lusitania.domain.dom This record defines a system named ``lusitania'' with a specified ethernet address, two IP addresses, and a fully qualified domain name. The ``proto=il'' tuple indicates that the system speaks IL, the Plan 9 transport protocol of choice. By default, systems are assumed only to speak TCP. Other useful attributes include: ! auth default Plan 9 authentication server ! cpu default Plan 9 cpu server ! dns default DNS server (can be more than one) ! dnsdomain default DNS domain suffix (can be more than one) ! fs default Plan 9 file server ! ipgw IP gateway ! ipmask IP network mask ! ipsubmask IP subnetwork mask ! ntp default NTP server ! nntp default NNTP server ! smtp default SMTP server IP HIERARCHY WALKING Most information in the database is not stored in each system's record. Instead, the database query function ndbipinfo (see ndb(2)) and its simple command-line interface ndb/ipquery (see ndb(8)) understand about the hierarchy of IP networks. When an attribute, say `fs', is needed for a system, the query routines start by looking up that system's network database record. If it has an fs= entry, ndbipinfo returns that value. Otherwise, ndbipinfo notes the system's IP address and walks down the IP hierarchy through the database, starting with the default IP network for the address. Specifically, it starts with the default IP mask for the address, and'ing it with the IP address to find the default IP network. Suppose our address is 10.247.62.235, as above. The default IP mask for the address is 255.0.0.0, so the default IP network is 10.0.0.0. Ndbipinfo looks for an ip=10.0.0.0 entry with an ipmask=255.0.0.0 entry. Suppose we find ! ipnet=ten-net ip=10.0.0.0 ipmask=255.0.0.0 ! ipsubmask=255.255.255.0 ! smtp=mailserver.domain.dom ! ntp=ntpserver.domain.dom ! fs=myfs The entry says that the network is composed of smaller subnetworks with mask 255.255.255.0, so we look for an entry for IP network 10.247.62.0 with the appropriate mask. Suppose we find (the value in the ipnet= tuple is irrelevant) ! ipnet=my-net ip=10.247.62.0 ipmask=255.255.255.0 ! fs=my-other-fs ! ipgw=10.247.62.1 Since there's no ipsubmask entry, we stop the walk, returning ``my-other-fs'', as it is the fs= entry for the smallest subnet we found. Note that the my-net record entry trumps the ten-net record entry, just as an fs= entry in the lusitania record would trump both of them. If we hadn't found the fs= entry in my-net, we would have used the ten-net one. The program ndb/ipquery (see ndb(8)) is good for testing that you have your network set up as you want, and that the IP hierarchy walks are happening as expected. The default IP submasks are determined by the first number in the address: ! 0-127 255.0.0.0 ! 128-191 255.255.0.0 ! 192-223 255.255.255.0 ! 224-239 These are reserved for multicast addresses ! 240-255 These are reserved for future use (This is an internet standard, not a Plan 9 one.) CONFIGURATION Having read the preceding sections you can begin to define the layout of your network. An example configuration exists at /lib/ndb/local.complicated. A minimal configuration is presented here. ! database= ! file=/lib/ndb/local ! file=/lib/ndb/common ! ! ipnet=mynetwork ip=192.168.0.0 ipmask=255.255.255.0 ! ipgw=192.168.0.1 ! dns=1.2.3.4 ! auth=mauretania ! ! ip=192.168.0.2 sys=mauretania ! ip=192.168.0.3 sys=aquitania In this example we'll setup up the machine 'mauretania' as our first Plan 9 machine and make it the default authentication server for our 192.168.0.x subnet. We'll give our machine the IP address 192.168.0.2. If you don't intend to have internet connectivity you may omit the ipgw and dns items. IPCONFIG Note that above we have defined two systems, one is 'mauretania', the other is called 'aquitania'. How does Plan 9 determine our machine is supposed to be 'mauretania'? The answer is ip/ipconfig. When a Plan 9 machine boots, it runs the configuration script /rc/bin/termrc or /rc/bin/cpurc, depending on whether it is a terminal or a CPU server. In /rc/bin/termrc you will find the line ! ip/ipconfig >/dev/null >[2=1] This line causes the machine to look for a DHCP server to supply it with configuration information. You can set up a Plan 9 CPU/authentication server to run a DHCP server. When you do this the server will look up it's network database and serve out the configuration defaults. Nevertheless, there isn't yet enough information there to give a specific machine a fixed IP. One way of doing this is to bind a specific configuration to a specific network card's MAC address. Each physical network card is given an unique MAC address when manufactured. You can find out your card's MAC address by typing the line ! cat /net/ether0/addr (If there isn't a /net/ether0 directory then Plan 9 did not find an ethernet card on your system.) You can now add the MAC address as an attribute of the configuration line in the ndb like ! ip=192.168.0.2 sys=mauretania ether=abc12345def where 'abc12345def' is the MAC address. Of course if there isn't a Plan 9 DHCP server on the network, this method won't work. When setting up your first Plan 9 machine, you can modify the ip/ipconfig line to specify a specific gateway, ip, and ip-mask to use. ! ip/ipconfig -g 192.168.0.1 ether /net/ether0 192.168.0.2 255.255.255.0 You now have enough information to follow the instructions for [Configuring a Standalone CPU Server]. It will guide you in setting up a system suitable as any combination of CPU server, Authentication server, DHCP server, and even a light-weight kfs (file) server. For a proper file server see [Installing a Plan 9 file server]. TROUBLESHOOTING If ipconfig gives an error of the form ! ip/ipconfig: binding device: '/net/ether0' cs: file does not exist it indicates that the kernel has not detected your network card. For a PC, make sure that your plan9.ini(8) file specifies the proper network driver. If that doesn't help, it could be that the proper network driver is not compiled into the kernel that you're using. See [Compiling kernels] for information on how to make a new kernel. If after installing a fossil+venti system you get an error message like ! ndb/dns: can't read my ip address you might want to edit the /rc/bin/termrc to omit the test conditions for both ip/ipconfig and ndb/dns - the relevant section should just read something like: ! ip/ipconfig >/dev/null >[2=1] ! ndb/dns -rf $NDBFILE QUERY TOOLS ndb/query and ndb/ipquery look directly in the ndb files. ndb/query does simple direct queries based on the given attribute and value, ndb/ipquery searches more extensively up through the subnet hierarchy. They are both good tools to check basic functioning of an ndb file. If they don't produce sensible results, it's unlikely cs will. ndb/query and (probably) ndb/ipquery do not talk to ndb/cs or ndb/dns at all. ndb/csquery simply opens /net/cs and speaks its protocol, which expects strings of the form ! net!host!service and replies with translations of them: ! term% ndb/csquery ! > net!plan9.bell-labs.com!9fs ! /net/il/clone 204.178.31.2!17008!fasttimeout ! /net/tcp/clone 204.178.31.2!564 ! /net/il/clone 204.178.31.2!17008 cs relies on dns to translate domain names to ip addresses. It does not expect a plain name such as `p9'. It translates dial(2) addresses. There's a special case that's also useful in checking whether your host, subnet and net defaults for services are reasonable. ! net!$attr!service looks for the given attribute `attr' through the subnet hierarchy starting at the host and working up. Thus the dial(2) string `net!$fs!9fs' dials the (default) file server configured for the current node, and the translation can be checked by: ! term% ndb/csquery ! > net!$fs!9fs ! /net/il/clone 144.32.112.69!17008!fasttimeout ! /net/tcp/clone 144.32.112.69!564 ! /net/il/clone 144.32.112.69!17008 i don't know without a lot of grepping how much the $attr is used now but it is used to find an authentication server in the absence of an authdom (see /sys/src/libauthsrv/authdial.c). It doesn't really matter because the point here is that $xyz can be used to check that cs gives a sensible value for xyz for the current node. ndb/dnsquery opens /net/dns and uses its protocol: ! ndb/dnsquery ! > bell-labs.com ns ! bell-labs.com ns ns.research.att.com ! bell-labs.com ns yeats.pa.bell-labs.com ! bell-labs.com ns crufty.research.bell-labs.com ! bell-labs.com ns ns1.research.bell-labs.com ! bell-labs.com ns dirty.research.bell-labs.com ! bell-labs.com ns ns2.research.bell-labs.com ! > plan9.bell-labs.com ! plan9.bell-labs.com ip 204.178.31.2 BOOTING VIA PXE To boot a machine using PXE set add an entry to /lib/ndb/local something like: ! sys=doris ether=03294ea93902 ! ip=192.168.0.32 ! dom=doris.mydomain.com ! bootf=/386/9pxeload ! authdom=mydomain.com The intial boot via DHCP will discover the ether config and download 9pxeload. This will then pull down its plan9.ini file which it expects to find in the file: ! /cfg/pxe/. bootstrap then continues as usual. SEE ALSO [Dialup modem config], [DNSMASQ], ipconfig(8), ndb(8), ndb(6), [The Organization of Networks in Plan 9 | http://plan9.bell-labs.com/sys/doc/net.html] ( /sys/doc/net/net.ps ) ------------------------------------------------------ Todo: BOOTSTRAPPING OTHER SYSTEMS ... explain items in cpurc ndb/cs ndb/dns ip/dhcp ip/tftp aux/timesync /net/ndb auth/keyfs aux/listen