|
@@ -689,7 +689,7 @@ as a dependency earlier -->
|
|
|
</section>
|
|
|
|
|
|
|
|
|
- <section>
|
|
|
+ <section id="configure">
|
|
|
<title>Configure before the build</title>
|
|
|
<para>
|
|
|
BIND 10 uses the GNU Build System to discover build environment
|
|
@@ -759,7 +759,10 @@ as a dependency earlier -->
|
|
|
If the configure fails, it may be due to missing or old
|
|
|
dependencies.
|
|
|
</para>
|
|
|
-
|
|
|
+
|
|
|
+ <note>
|
|
|
+ <para>For notes on configuring and building DHCPv6 with MySQL see <xref linkend="dhcp6-install">.</xref></para>
|
|
|
+ </note>
|
|
|
</section>
|
|
|
|
|
|
<section>
|
|
@@ -3323,20 +3326,20 @@ then change those defaults with config set Resolver/forward_addresses[0]/address
|
|
|
|
|
|
<note>
|
|
|
<para>
|
|
|
- As of December 2011, both DHCPv4 and DHCPv6 components are
|
|
|
- skeleton servers. That means that while they are capable of
|
|
|
- performing DHCP configuration, they are not fully functional
|
|
|
- yet. In particular, neither has functional lease
|
|
|
+ As of November 2012, the DHCPv4 component is a
|
|
|
+ skeleton server. That means that while it is capable of
|
|
|
+ performing DHCP configuration, it is not fully functional.
|
|
|
+ In particular, it does not have a functional lease
|
|
|
databases. This means that they will assign the same, fixed,
|
|
|
hardcoded addresses to any client that will ask. See <xref
|
|
|
- linkend="dhcp4-limit"/> and <xref linkend="dhcp6-limit"/> for
|
|
|
+ linkend="dhcp4-limit"/> for a
|
|
|
detailed description.
|
|
|
</para>
|
|
|
</note>
|
|
|
|
|
|
<section id="dhcp4-usage">
|
|
|
<title>DHCPv4 Server Usage</title>
|
|
|
- <para>BIND 10 provides the DHCPv4 server component since December
|
|
|
+ <para>BIND 10 has provided the DHCPv4 server component since December
|
|
|
2011. It is a skeleton server and can be described as an early
|
|
|
prototype that is not fully functional yet. It is mature enough
|
|
|
to conduct first tests in lab environment, but it has
|
|
@@ -3496,8 +3499,8 @@ const std::string HARDCODED_SERVER_ID = "192.0.2.1";</screen>
|
|
|
|
|
|
<chapter id="dhcp6">
|
|
|
<title>DHCPv6 Server</title>
|
|
|
- <para>Dynamic Host Configuration Protocol for IPv6 (DHCPv6) is
|
|
|
- specified in RFC3315. BIND 10 provides DHCPv6 server implementation
|
|
|
+ <para>The Dynamic Host Configuration Protocol for IPv6 (DHCPv6) is
|
|
|
+ specified in RFC3315. BIND 10 provides a DHCPv6 server implementation
|
|
|
that is described in this chapter. For a description of the DHCPv4
|
|
|
server implementation, see <xref linkend="dhcp4"/>.
|
|
|
</para>
|
|
@@ -3509,32 +3512,92 @@ const std::string HARDCODED_SERVER_ID = "192.0.2.1";</screen>
|
|
|
url="https://lists.isc.org/mailman/listinfo/bind10-dev">BIND 10
|
|
|
developers mailing list</ulink>.</para>
|
|
|
|
|
|
- <para>The DHCPv4 and DHCPv6 components in BIND 10 architecture are
|
|
|
- internally code named <quote>Kea</quote>.</para>
|
|
|
-
|
|
|
<note>
|
|
|
<para>
|
|
|
- As of December 2011, both DHCPv4 and DHCPv6 components are
|
|
|
- skeleton servers. That means that while they are capable of
|
|
|
- performing DHCP configuration, they are not fully functional
|
|
|
- yet. In particular, neither has functional lease
|
|
|
- databases. This means that they will assign the same, fixed,
|
|
|
- hardcoded addresses to any client that will ask. See <xref
|
|
|
- linkend="dhcp4-limit"/> and <xref linkend="dhcp6-limit"/> for
|
|
|
- detailed description.
|
|
|
+ As of November 2012, the DHCPv6 component is partially functioning,
|
|
|
+ having the following capabilities:
|
|
|
</para>
|
|
|
+ <itemizedlist>
|
|
|
+ <listitem>
|
|
|
+ <simpara>DHCPv6 server able to allocate leases (but not renew them).</simpara>
|
|
|
+ </listitem>
|
|
|
+ <listitem>
|
|
|
+ <simpara>Some configuration available through the BIND 10 configuration mechanism.</simpara>
|
|
|
+ </listitem>
|
|
|
+ <listitem>
|
|
|
+ <simpara>Lease storage in a MySQL database.</simpara>
|
|
|
+ </listitem>
|
|
|
+ </itemizedlist>
|
|
|
</note>
|
|
|
|
|
|
- <section id="dhcp6-usage">
|
|
|
- <title>DHCPv6 Server Usage</title>
|
|
|
+ <section id="dhcp6-install">
|
|
|
+ <title>DHCPv6 Server Build and Installation</title>
|
|
|
<para>
|
|
|
- BIND 10 provides the DHCPv6 server component since September
|
|
|
- 2011. It is a skeleton server and can be described as an early
|
|
|
- prototype that is not fully functional yet. It is mature
|
|
|
- enough to conduct first tests in lab environment, but it has
|
|
|
- significant limitations. See <xref linkend="dhcp6-limit"/> for
|
|
|
- details.
|
|
|
+ DHCPv6 is part of the BIND suite of programs and is built as part of
|
|
|
+ the build of BIND 10. With the use of MySQL, some additional
|
|
|
+ installation steps are needed:
|
|
|
</para>
|
|
|
+ <section>
|
|
|
+ <title>Install MySQL</title>
|
|
|
+ <para>
|
|
|
+ Install MySQL according to the instructions for your system. The client development
|
|
|
+ libraries must be installed.
|
|
|
+ </para>
|
|
|
+ </section>
|
|
|
+ <section>
|
|
|
+ <title>Build and Install BIND 10</title>
|
|
|
+ <para>
|
|
|
+ Build and install BIND 10 as described in <xref linkend="installation"/>, with
|
|
|
+ the following modification: to enable the MySQL database code, the
|
|
|
+ "configure" step (see <xref linkend="configure"/>), specify the location of the
|
|
|
+ MySQL configuration program "mysql_config" with the "--with-mysql-config" switch,
|
|
|
+ i.e.
|
|
|
+ <screen><userinput>./configure [other-options] --with-dhcp-mysql</userinput></screen>
|
|
|
+ ...if MySQL was installed in the default location, or:
|
|
|
+ <screen><userinput>./configure [other-options] --with-dhcp-mysql=<path-to-mysql_config></userinput></screen>
|
|
|
+ ...if not.
|
|
|
+ </para>
|
|
|
+ </section>
|
|
|
+ <section>
|
|
|
+ <title>Create MySQL Database and BIND 10 User</title>
|
|
|
+ <para>
|
|
|
+ The next task is to create both the DHCPv6 lease database and the user under which the DHCPv6 server will
|
|
|
+ access it. Although the intention is to have the name of the database and the user configurable,
|
|
|
+ at the moment they are hard-coded as "kea", as is the associated password. ("kea" is an internal
|
|
|
+ code name for BIND 10 DHCP.) There are a number of steps required:
|
|
|
+ </para>
|
|
|
+ <para>
|
|
|
+ 1. Log into MySQL as "root":
|
|
|
+ <screen>$ <userinput>mysql -u root -p</userinput>
|
|
|
+Enter password:<userinput/>
|
|
|
+ :<userinput/>
|
|
|
+mysql></screen>
|
|
|
+ </para>
|
|
|
+ <para>
|
|
|
+ 2. Create the database:
|
|
|
+ <screen>mysql> <userinput>CREATE DATABASE kea;</userinput></screen>
|
|
|
+ </para>
|
|
|
+ <para>
|
|
|
+ 3. Create the database tables:
|
|
|
+ <screen>mysql> <userinput>CONNECT kea;</userinput>
|
|
|
+mysql> <userinput>SOURCE <path-to-bind10>/share/bind10-devel/dhcpdb_create.mysql</userinput></screen>
|
|
|
+ </para>
|
|
|
+ <para>
|
|
|
+ 4. Create the user under which BIND 10 will access the database and grant it access to the database tables:
|
|
|
+ <screen>mysql> <userinput>CREATE USER 'kea'@'localhost' IDENTIFIED BY 'kea';</userinput>
|
|
|
+mysql> <userinput>GRANT ALL ON kea.* TO 'kea'@'localhost';</userinput></screen>
|
|
|
+ </para>
|
|
|
+ <para>
|
|
|
+ 5. Exit MySQL:
|
|
|
+ <screen>mysql> <userinput>quit</userinput>
|
|
|
+Bye<userinput/>
|
|
|
+$</screen>
|
|
|
+ </para>
|
|
|
+ </section>
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <section id="dhcp6-usage">
|
|
|
+ <title>DHCPv6 Server Usage</title>
|
|
|
|
|
|
<para>
|
|
|
<command>b10-dhcp6</command> is a BIND 10 component and is being
|
|
@@ -3546,7 +3609,7 @@ const std::string HARDCODED_SERVER_ID = "192.0.2.1";</screen>
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- To shutdown running <command>b10-dhcp6</command>, please use the
|
|
|
+ To shutdown running <command>b10-dhcp6</command>, use use the
|
|
|
following command:
|
|
|
<screen>> <userinput>Dhcp6 shutdown</userinput></screen>
|
|
|
or
|
|
@@ -3558,12 +3621,11 @@ const std::string HARDCODED_SERVER_ID = "192.0.2.1";</screen>
|
|
|
During start-up the server will detect available network interfaces
|
|
|
and will attempt to open UDP sockets on all interfaces that
|
|
|
are up, running, are not loopback, are multicast-capable, and
|
|
|
- have IPv6 address assigned.
|
|
|
-
|
|
|
- The server will then listen to incoming traffic. Currently
|
|
|
- supported client messages are SOLICIT and REQUEST. The server
|
|
|
+ have IPv6 address assigned. It will then listen to incoming traffic. The
|
|
|
+ currently supported client messages are SOLICIT and REQUEST. The server
|
|
|
will respond to them with ADVERTISE and REPLY, respectively.
|
|
|
-
|
|
|
+ </para>
|
|
|
+ <para>
|
|
|
Since the DHCPv6 server opens privileged ports, it requires root
|
|
|
access. Make sure you run this daemon as root.
|
|
|
</para>
|
|
@@ -3573,11 +3635,10 @@ const std::string HARDCODED_SERVER_ID = "192.0.2.1";</screen>
|
|
|
<section id="dhcp6-config">
|
|
|
<title>DHCPv6 Server Configuration</title>
|
|
|
<para>
|
|
|
- Once the server is started, it can be configured. To view the
|
|
|
+ Once the server has been started, it can be configured. To view the
|
|
|
current configuration, use the following command in <command>bindctl</command>:
|
|
|
- <screen>
|
|
|
- > <userinput>config show Dhcp6</userinput></screen>
|
|
|
- When starting Dhcp6 daemon for the first time, the default configuration
|
|
|
+ <screen>> <userinput>config show Dhcp6</userinput></screen>
|
|
|
+ When starting the Dhcp6 daemon for the first time, the default configuration
|
|
|
will be available. It will look similar to this:
|
|
|
<screen>
|
|
|
> <userinput>config show Dhcp6</userinput>
|
|
@@ -3596,14 +3657,14 @@ Dhcp6/subnet6 [] list (default)</screen>
|
|
|
<screen>
|
|
|
> <userinput>config set Dhcp6/valid-lifetime 7200</userinput>
|
|
|
> <userinput>config commit</userinput></screen>
|
|
|
- Please note that most Dhcp6 parameters are of global scope
|
|
|
+ Most Dhcp6 parameters are of global scope
|
|
|
and apply to all defined subnets, unless they are overridden on a
|
|
|
per-subnet basis.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- The essential role of DHCPv6 server is address assignment. The server
|
|
|
- has to be configured with at least one subnet and one pool of dynamic
|
|
|
+ The essential role of a DHCPv6 server is address assignment. For this,
|
|
|
+ the server has to be configured with at least one subnet and one pool of dynamic
|
|
|
addresses to be managed. For example, assume that the server
|
|
|
is connected to a network segment that uses the 2001:db8:1::/64
|
|
|
prefix. The Administrator of that network has decided that addresses from range
|
|
@@ -3655,24 +3716,49 @@ Dhcp6/subnet6 [] list (default)</screen>
|
|
|
2001:db8:: address may be assigned as well. If you want to avoid this,
|
|
|
please use min-max notation.
|
|
|
</para>
|
|
|
-
|
|
|
<para>
|
|
|
- Note: Although configuration is now accepted, it is not internally used
|
|
|
- by they server yet. At this stage of development, the only way to alter
|
|
|
- server configuration is to modify its source code. To do so, please edit
|
|
|
- src/bin/dhcp6/dhcp6_srv.cc file, modify the following parameters and
|
|
|
- recompile:
|
|
|
+ Options can also be configured: the following commands configure
|
|
|
+ the DNS-SERVERS option for all subnets with the following addresses:
|
|
|
+ 2001:db8:1::1 and 2001:db8:1::2
|
|
|
<screen>
|
|
|
-const std::string HARDCODED_LEASE = "2001:db8:1::1234:abcd";
|
|
|
-const uint32_t HARDCODED_T1 = 1500; // in seconds
|
|
|
-const uint32_t HARDCODED_T2 = 2600; // in seconds
|
|
|
-const uint32_t HARDCODED_PREFERRED_LIFETIME = 3600; // in seconds
|
|
|
-const uint32_t HARDCODED_VALID_LIFETIME = 7200; // in seconds
|
|
|
-const std::string HARDCODED_DNS_SERVER = "2001:db8:1::1";</screen>
|
|
|
-
|
|
|
- Lease database and configuration support is planned for 2012.
|
|
|
+> <userinput>config add Dhcp6/option-data</userinput>
|
|
|
+> <userinput>config set Dhcp6/option-data[0]/name "dns-servers"</userinput>
|
|
|
+> <userinput>config set Dhcp6/option-data[0]/code 23</userinput>
|
|
|
+> <userinput>config set Dhcp6/option-data[0]/data "2001 0DB8 0001 0000 0000 0000</userinput>
|
|
|
+ <userinput>0000 0001 2001 0DB8 0001 0000 0000 0000 0000 0002"</userinput>
|
|
|
+> <userinput>config commit</userinput>
|
|
|
+ </screen>
|
|
|
+ (The value for the setting of the "data" element is split across two
|
|
|
+ lines in this document for clarity: when entering the command, all the
|
|
|
+ string should be entered on the same line.)
|
|
|
</para>
|
|
|
-
|
|
|
+ <para>
|
|
|
+ Currently the only way to set option data is to specify the
|
|
|
+ data as a string of hexadecimal digits. It is planned to allow
|
|
|
+ alternative ways of specifying the data as a comma-separated list,
|
|
|
+ e.g. "2001:db8:1::1,2001:db8:1::2".
|
|
|
+ </para>
|
|
|
+ <para>
|
|
|
+ As with global settings, it is also possible to override options on a
|
|
|
+ per-subnet basis, e.g. the following commands override the global DNS
|
|
|
+ servers option for a particular subnet, setting a single DNS server with
|
|
|
+ address 2001:db8:1::3.
|
|
|
+ <screen>
|
|
|
+> <userinput>config add Dhcp6/subnet6[0]/option-data</userinput>
|
|
|
+> <userinput>config set Dhcp6/subnet6[0]/option-data[0]/name "dns-servers"</userinput>
|
|
|
+> <userinput>config set Dhcp6/subnet6[0]/option-data[0]/code 23</userinput>
|
|
|
+> <userinput>config set Dhcp6/subnet6[0]/option-data[0]/data "2001 0DB8 0001 0000</userinput>
|
|
|
+ <userinput>0000 0000 0000 0003"</userinput>
|
|
|
+> <userinput>config commit</userinput></screen>
|
|
|
+ (As before, the setting of the "data" element has been split across two
|
|
|
+ lines for clarity.)
|
|
|
+ </para>
|
|
|
+ <note>
|
|
|
+ <para>
|
|
|
+ With this version of BIND 10, there are a number of known limitations
|
|
|
+ and problems in the DHCPv6 server. See <xref linkend="dhcp6-limit"/>.
|
|
|
+ </para>
|
|
|
+ </note>
|
|
|
</section>
|
|
|
|
|
|
<section id="dhcp6-std">
|
|
@@ -3693,30 +3779,39 @@ const std::string HARDCODED_DNS_SERVER = "2001:db8:1::1";</screen>
|
|
|
|
|
|
<section id="dhcp6-limit">
|
|
|
<title>DHCPv6 Server Limitations</title>
|
|
|
- <para> These are the current limitations of the DHCPv6 server
|
|
|
+ <para> These are the current limitations and known problems
|
|
|
+ with the the DHCPv6 server
|
|
|
software. Most of them are reflections of the early stage of
|
|
|
development and should be treated as <quote>not implemented
|
|
|
yet</quote>, rather than actual limitations.</para>
|
|
|
<para>
|
|
|
<itemizedlist>
|
|
|
<listitem>
|
|
|
- <simpara>Relayed traffic is not supported.</simpara>
|
|
|
+ <para>The DHCPv6 server has only been tested on Debian
|
|
|
+ operating systems. There are known problems with the
|
|
|
+ handling of packets in CentOS and RHEL.</para>
|
|
|
</listitem>
|
|
|
<listitem>
|
|
|
- <simpara><command>b10-dhcp6</command> provides a single,
|
|
|
- fixed, hardcoded lease to any client that asks. There is no
|
|
|
- lease manager implemented. If two clients request addresses,
|
|
|
- they will both get the same fixed address.</simpara>
|
|
|
+ <para>Relayed traffic is not supported.</para>
|
|
|
+ </listitem>
|
|
|
+ <listitem>
|
|
|
+ <para><command>b10-dhcp6</command> only supports
|
|
|
+ a limited number of configuration options.</para>
|
|
|
</listitem>
|
|
|
<listitem>
|
|
|
- <simpara><command>b10-dhcp6</command> does not support any
|
|
|
- configuration mechanisms yet. The whole configuration is
|
|
|
- currently hardcoded. The only way to tweak configuration
|
|
|
- is to directly modify source code. See see <xref
|
|
|
- linkend="dhcp6-config"/> for details.</simpara>
|
|
|
+ <para>
|
|
|
+ On startup, the DHCPv6 server does not get the full configuration from
|
|
|
+ BIND 10. To remedy this, after starting BIND 10, modify any parameter
|
|
|
+ and commit the changes, e.g.
|
|
|
+ <screen>
|
|
|
+> <userinput>config show Dhcp6/renew-timer</userinput>
|
|
|
+Dhcp6/renew-timer 1000 integer (default)
|
|
|
+> <userinput>config set Dhcp6/renew-timer 1001</userinput>
|
|
|
+> <userinput>config commit</userinput></screen>
|
|
|
+ </para>
|
|
|
</listitem>
|
|
|
<listitem>
|
|
|
- <simpara>Upon start, the server will open sockets on all
|
|
|
+ <para>Upon start, the server will open sockets on all
|
|
|
interfaces that are not loopback, are up, running and are
|
|
|
multicast capable and have IPv6 address. Support for
|
|
|
multiple interfaces is not coded in reception routines yet,
|
|
@@ -3724,34 +3819,29 @@ const std::string HARDCODED_DNS_SERVER = "2001:db8:1::1";</screen>
|
|
|
interfaces and <command>b10-dhcp6</command> happens to
|
|
|
listen on wrong interface, the easiest way to work around
|
|
|
this problem is to turn down other interfaces. This
|
|
|
- limitation will be fixed shortly.</simpara>
|
|
|
+ limitation will be fixed shortly.</para>
|
|
|
</listitem>
|
|
|
<listitem>
|
|
|
- <simpara>ORO (Option Request Option, a list of options
|
|
|
- requested by a client) is currently ignored and server
|
|
|
- assigns DNS SERVER option.</simpara>
|
|
|
+ <para>ORO (Option Request Option, a list of options
|
|
|
+ requested by a client) is currently unsupported.</para>
|
|
|
</listitem>
|
|
|
<listitem>
|
|
|
- <simpara>Temporary addresses are not supported yet.</simpara>
|
|
|
+ <para>Temporary addresses are not supported.</para>
|
|
|
</listitem>
|
|
|
<listitem>
|
|
|
- <simpara>Prefix delegation is not supported yet.</simpara>
|
|
|
+ <para>Prefix delegation is not supported.</para>
|
|
|
</listitem>
|
|
|
<listitem>
|
|
|
- <simpara>Address renewal (RENEW), rebinding (REBIND),
|
|
|
+ <para>Address renewal (RENEW), rebinding (REBIND),
|
|
|
confirmation (CONFIRM), duplication report (DECLINE) and
|
|
|
- release (RELEASE) are not supported yet.</simpara>
|
|
|
+ release (RELEASE) are not supported.</para>
|
|
|
</listitem>
|
|
|
<listitem>
|
|
|
- <simpara>DNS Update is not supported yet.</simpara>
|
|
|
+ <para>DNS Update is not supported.</para>
|
|
|
</listitem>
|
|
|
<listitem>
|
|
|
- <simpara>Interface detection is currently working on Linux
|
|
|
- only. See <xref linkend="iface-detect"/> for details.</simpara>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <simpara>-v (verbose) command line option is currently the
|
|
|
- default, and cannot be disabled.</simpara>
|
|
|
+ <para>Interface detection is currently working on Linux
|
|
|
+ only. See <xref linkend="iface-detect"/> for details.</para>
|
|
|
</listitem>
|
|
|
</itemizedlist>
|
|
|
</para>
|
|
@@ -3761,29 +3851,40 @@ const std::string HARDCODED_DNS_SERVER = "2001:db8:1::1";</screen>
|
|
|
|
|
|
<chapter id="libdhcp">
|
|
|
<title>libdhcp++ library</title>
|
|
|
- <para>libdhcp++ is a common library written in C++ that handles
|
|
|
- many DHCP-related tasks, like DHCPv4 and DHCPv6 packets parsing,
|
|
|
- manipulation and assembly, option parsing, manipulation and
|
|
|
- assembly, network interface detection and socket operations, like
|
|
|
- socket creations, data transmission and reception and socket
|
|
|
- closing.
|
|
|
+ <para>
|
|
|
+ libdhcp++ is a common library written in C++ that handles
|
|
|
+ many DHCP-related tasks, including
|
|
|
+ <itemizedlist>
|
|
|
+ <listitem>
|
|
|
+ <simpara>DHCPv4 and DHCPv6 packets parsing, manipulation and assembly</simpara>
|
|
|
+ </listitem>
|
|
|
+ <listitem>
|
|
|
+ <simpara>Option parsing, manipulation and assembly</simpara>
|
|
|
+ </listitem>
|
|
|
+ <listitem>
|
|
|
+ <simpara>Network interface detection</simpara>
|
|
|
+ </listitem>
|
|
|
+ <listitem>
|
|
|
+ <simpara>Socket operations such as creation, data transmission and reception and socket closing.</simpara>
|
|
|
+ </listitem>
|
|
|
+ </itemizedlist>
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
While this library is currently used by
|
|
|
<command>b10-dhcp4</command> and <command>b10-dhcp6</command>
|
|
|
- only, it is designed to be portable, universal library useful for
|
|
|
+ only, it is designed to be portable, universal library, useful for
|
|
|
any kind of DHCP-related software.
|
|
|
</para>
|
|
|
|
|
|
<section id="iface-detect">
|
|
|
<title>Interface detection</title>
|
|
|
- <para>Both DHCPv4 and DHCPv6 components share network
|
|
|
+ <para>Both the DHCPv4 and DHCPv6 components share network
|
|
|
interface detection routines. Interface detection is
|
|
|
currently only supported on Linux systems.</para>
|
|
|
|
|
|
- <para>For non-Linux systems, there is currently stub
|
|
|
- implementation provided. Interface manager detects loopback
|
|
|
+ <para>For non-Linux systems, there is currently a stub
|
|
|
+ implementation provided. The interface manager detects loopback
|
|
|
interfaces only as their name (lo or lo0) can be easily predicted.
|
|
|
Please contact the BIND 10 development team if you are interested
|
|
|
in running DHCP components on systems other than Linux.</para>
|