BIND 10 trac1213, updated. 1817f1e8fd4a3635b8b5e0d581f6a2aa61b5e955 [1213] ChangeLog entry for #1213

BIND 10 source code commits bind10-changes at lists.isc.org
Tue Oct 18 10:04:17 UTC 2011


The branch, trac1213 has been updated
       via  1817f1e8fd4a3635b8b5e0d581f6a2aa61b5e955 (commit)
       via  68ee3818bcbecebf3e6789e81ea79d551a4ff3e8 (commit)
       via  5bb1a0ebbed603d81656d5e87196191f1b00aad5 (commit)
       via  fd5db1f7aa6f49091b4e66193b0379679eede4c4 (commit)
       via  190d4380c54493561eda99d66739f31e515f8e4e (commit)
       via  021f3f24fcd053a92b6ee305b984f1a6a550cebc (commit)
       via  937b5a6f47d4506193de9a3ed77adcef2cb1fd35 (commit)
       via  c110fcc95f61b07871fd6fe7e24a495a3f49b89c (commit)
       via  58e72cb159391aa0c7832d08ddb0df361514918e (commit)
       via  26f4192ca701bafca9460e994c61715916091e37 (commit)
       via  86b3f90af4f0f643e44fd3f7cfd11d89a42e4ebd (commit)
       via  67ea6de047d4dbd63c25fe7f03f5d5cc2452ad7d (commit)
       via  01bc2a7ff47131144717e923108f71eda283475b (commit)
       via  cee641fd3d12341d6bfce5a6fbd913e3aebc1e8e (commit)
       via  ed787b2156b0a7a88ace941447783c53991a254c (commit)
       via  e9c6c3cf86e3b1b02c64bf567f0c20f6c1e2f589 (commit)
       via  004e1238d580d601f7fd8847ff1c4933de465942 (commit)
       via  5da6a0f0e8829140999c69bfb551a305c6bf0257 (commit)
       via  25ce3ceaf98ed34ad3a4ebe3cac901c0b6e15a97 (commit)
       via  5756a9c761748b960b974f422963fbf8e5498378 (commit)
       via  566e635f4f2647a82457acb9c047d890f4cb459b (commit)
       via  76f58b2ff1ebc572cef465f5be1445e08e4bf0fb (commit)
       via  f89dbf486bbbd41c3f4e85c15d2cda91706a37ba (commit)
       via  a91fbbe9905680873c4f0acf5cff1d712aa68831 (commit)
       via  86cab473cc0113b0f83755c14db4035bae675065 (commit)
       via  ca22c5ab2322ab7620e4b84589da6761fdaa3b62 (commit)
       via  838acbebc584fee662143c303b7a110563f4e0de (commit)
       via  c5d29c73bcd554111ada4dec49f61cfde497cb6c (commit)
       via  4ec7a8d9ab678f28abf3b37d40acdf159344cf0f (commit)
       via  92b2aa9c962e9ca1cec80f44bee713afa1ac53f3 (commit)
       via  6b9d28f7602143bb85fcfcefbaa35cde95fdbde3 (commit)
       via  223b19a30e4897c7281bb40c9f366a01c8f449ca (commit)
       via  bfea61834be28bc3c2413afb586971fc04056a41 (commit)
       via  620072324ac5f111f8fd40a4ba6d10879c44e211 (commit)
       via  522d27a63d1ff318173e7e4aeb6c1265aba93ca5 (commit)
       via  c4291199d0ebab1cdb49b80101239b9582c13148 (commit)
       via  9d9680719eb0ce32ea039386bfe767dfa41d1968 (commit)
       via  2f39435c981e3cb14d2c4e9551af93fbbfc28109 (commit)
       via  2276752655f67044fb6ae8f7e14e9ba5f6ee6638 (commit)
       via  54ba29f03a62c84ee9cbf1c92db74b57327a1868 (commit)
       via  6433a51cb6e72309eb027411ea4fa98adb97a7f8 (commit)
       via  4865dbd45b6f94b20b562b11224754313e74bf25 (commit)
       via  c7b8783766258a4321622b7d7e2bb02a647d0864 (commit)
       via  b8d8ea4cfb87fd12abe113cf63edbae4a342e6c1 (commit)
       via  6ce36056a14fad339ffc6528343aadf12065ca44 (commit)
       via  8dbb407ba4adc1bbaf061b5680bafd35c778cd90 (commit)
       via  f9ff938c75816df97f318a839f01be3f01c93f2a (commit)
       via  a69020025379d5430fff394465348aa430533458 (commit)
       via  af27ec87f09d82918b96c9dd6d236b4e39989f7f (commit)
       via  b47533e918cb5b0c2befe7b0da315819b009c47f (commit)
       via  f4c7155d41cb008a1a180e567e142ce096a21b88 (commit)
       via  d647a4589362d2b6efee86e58c9fb38e7084deb4 (commit)
       via  5f9a52abbd9f785ab878e71907c8b6dfa587fab1 (commit)
       via  a6646243196e059b1c137c939787117e78523b57 (commit)
       via  9578ddf805881e30dc4ae2124bcae6b24b580f65 (commit)
       via  c3dafdb35cc8cd72e972a0d8212ddea3c09c330c (commit)
       via  a3e0ed25ca88b74d92e9bfa11414e137b5982de8 (commit)
       via  554a8b40e84b9f778f398b7ff15d86140255bc89 (commit)
       via  41040f22c80fd9f300f4f75cae3177a5360a80e2 (commit)
       via  163fa80307a1ab8882a1895ab1e2e12d22c8fd4b (commit)
       via  337198f6b8e619d836e9c51399be97e7a6038674 (commit)
       via  b0b09a77b7dab7b961f4424d05c135e9eb045b80 (commit)
       via  d1897d34676045b89edc09a767f8d0ab14d662c9 (commit)
       via  acb0565bb4ddaf1d51abc511459478e738dff6d7 (commit)
       via  99aa9fc05044158e0f41e56da538bd1162d869e2 (commit)
       via  e2c88f03e394ed8ebcfcff936ee888bf593e22d1 (commit)
       via  930d4317ed56bdb7cb0d7d53bac5db297ddd0551 (commit)
       via  1db00151f61cdd1c58bcd80dad38f3f97c67dae7 (commit)
       via  b684bcd2eb5a0def50c149319ab8df379155121f (commit)
       via  ada1705cfdea36539c48b1e7fc6a0c5cd7f3d8d5 (commit)
       via  fd39e4e890ce175901311b9e11291628743edde4 (commit)
       via  b9a2e86c2ee8d688a3e12877eb6dc4894a7eae24 (commit)
       via  ee7fff3113f67a7dddbf069e2a555e6dbac97f69 (commit)
       via  681e0e8b37fcf732b0f4caabae3695756e6a1e9f (commit)
       via  aadf8f9a5d8dfe13ae2196b61c406c8a8e1d05e7 (commit)
       via  c38fc5257ebbd0cd444e6b9cedb466b31df66cea (commit)
       via  ee8c0398005c5aff53be33b07d9d0b6fdd353175 (commit)
       via  45970604c644066bd34abd15c8877d5969462250 (commit)
       via  1bbe7018238856b949b449bdacb43bcf90c79bef (commit)
       via  d7711ce221b04a035afa9d454c8baf53ec0cb9f0 (commit)
       via  2878aadf0276c7a52832c7ca7f3bddf5e348d79c (commit)
       via  b9aefd1018b099666908d64650c8a5ea3e153ff4 (commit)
       via  0b6ac7ed34c708e6e92c41dc28bc8589864cecd3 (commit)
       via  b126cf8dbf225ff5b12c9a7b6a241d80babf8a42 (commit)
      from  ad26a33ce7624ea2a9b8685f1255db0c1f80bfa8 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 1817f1e8fd4a3635b8b5e0d581f6a2aa61b5e955
Author: Stephen Morris <stephen at isc.org>
Date:   Tue Oct 18 11:04:02 2011 +0100

    [1213] ChangeLog entry for #1213

commit 68ee3818bcbecebf3e6789e81ea79d551a4ff3e8
Merge: ad26a33ce7624ea2a9b8685f1255db0c1f80bfa8 5bb1a0ebbed603d81656d5e87196191f1b00aad5
Author: Stephen Morris <stephen at isc.org>
Date:   Tue Oct 18 10:41:45 2011 +0100

    Merge branch 'master' into trac1213

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                      |   49 +-
 README                                         |  218 +----
 configure.ac                                   |    2 +
 doc/Doxyfile                                   |    2 +-
 doc/guide/Makefile.am                          |    7 +-
 doc/guide/bind10-guide.html                    |  141 ++-
 doc/guide/bind10-guide.txt                     | 1201 ++++++++++++++++++++++++
 doc/guide/bind10-guide.xml                     |   71 +-
 doc/guide/bind10-messages.xml                  |  358 ++++++--
 src/bin/auth/tests/Makefile.am                 |    2 +-
 src/bin/bind10/Makefile.am                     |    1 +
 src/bin/bind10/bind10_src.py.in                |   16 +
 src/bin/cfgmgr/plugins/Makefile.am             |   11 +-
 src/bin/dhcp6/Makefile.am                      |   20 +-
 src/bin/dhcp6/dhcp6.h                          |  184 ----
 src/bin/dhcp6/dhcp6_srv.cc                     |  202 ++++-
 src/bin/dhcp6/dhcp6_srv.h                      |  150 +++-
 src/bin/dhcp6/iface_mgr.cc                     |  127 +--
 src/bin/dhcp6/iface_mgr.h                      |  282 ++++--
 src/bin/dhcp6/main.cc                          |   10 +-
 src/bin/dhcp6/pkt6.cc                          |   46 -
 src/bin/dhcp6/pkt6.h                           |   62 --
 src/bin/dhcp6/tests/Makefile.am                |    7 +-
 src/bin/dhcp6/tests/dhcp6_srv_unittest.cc      |  107 ++-
 src/bin/dhcp6/tests/iface_mgr_unittest.cc      |  179 +++-
 src/bin/dhcp6/tests/pkt6_unittest.cc           |   44 -
 src/bin/resolver/tests/Makefile.am             |    2 +-
 src/bin/sockcreator/tests/Makefile.am          |    2 +-
 src/bin/xfrin/b10-xfrin.8                      |   30 +-
 src/bin/xfrin/b10-xfrin.xml                    |    9 +-
 src/bin/xfrin/tests/xfrin_test.py              |   80 ++-
 src/bin/xfrin/xfrin.py.in                      |   46 +-
 src/bin/xfrin/xfrin.spec                       |    2 +-
 src/bin/xfrin/xfrin_messages.mes               |    6 +
 src/lib/Makefile.am                            |    2 +-
 src/lib/acl/tests/Makefile.am                  |    2 +-
 src/lib/asiodns/tests/Makefile.am              |    2 +-
 src/lib/asiolink/io_address.cc                 |   20 +-
 src/lib/asiolink/io_address.h                  |   16 +
 src/lib/asiolink/tests/Makefile.am             |    2 +-
 src/lib/asiolink/tests/io_address_unittest.cc  |   20 +
 src/lib/bench/Makefile.am                      |    2 +-
 src/lib/bench/tests/Makefile.am                |    2 +-
 src/lib/cache/tests/Makefile.am                |    2 +-
 src/lib/cc/tests/Makefile.am                   |    2 +-
 src/lib/config/tests/Makefile.am               |    4 +-
 src/lib/cryptolink/tests/Makefile.am           |    2 +-
 src/lib/datasrc/tests/Makefile.am              |    2 +-
 src/lib/dhcp/Makefile.am                       |   25 +
 src/lib/dhcp/README                            |   11 +
 src/lib/dhcp/dhcp6.h                           |  184 ++++
 src/lib/dhcp/libdhcp.cc                        |  130 +++
 src/lib/dhcp/libdhcp.h                         |   83 ++
 src/lib/dhcp/option.cc                         |  262 ++++++
 src/lib/dhcp/option.h                          |  273 ++++++
 src/lib/dhcp/option6_addrlst.cc                |  134 +++
 src/lib/dhcp/option6_addrlst.h                 |  127 +++
 src/lib/dhcp/option6_ia.cc                     |  139 +++
 src/lib/dhcp/option6_ia.h                      |  137 +++
 src/lib/dhcp/option6_iaaddr.cc                 |  129 +++
 src/lib/dhcp/option6_iaaddr.h                  |  146 +++
 src/lib/dhcp/pkt6.cc                           |  224 +++++
 src/lib/dhcp/pkt6.h                            |  234 +++++
 src/lib/dhcp/tests/Makefile.am                 |   42 +
 src/lib/dhcp/tests/libdhcp_unittest.cc         |  137 +++
 src/lib/dhcp/tests/option6_addrlst_unittest.cc |  231 +++++
 src/lib/dhcp/tests/option6_ia_unittest.cc      |  262 ++++++
 src/lib/dhcp/tests/option6_iaaddr_unittest.cc  |  101 ++
 src/lib/dhcp/tests/option_unittest.cc          |  279 ++++++
 src/lib/dhcp/tests/pkt6_unittest.cc            |  206 ++++
 src/lib/dhcp/tests/run_unittests.cc            |   27 +
 src/lib/dns/tests/Makefile.am                  |    2 +-
 src/lib/exceptions/tests/Makefile.am           |    2 +-
 src/lib/log/tests/Makefile.am                  |    6 +-
 src/lib/nsas/tests/Makefile.am                 |    2 +-
 src/lib/resolve/tests/Makefile.am              |    2 +-
 src/lib/server_common/tests/Makefile.am        |    2 +-
 src/lib/testutils/Makefile.am                  |    2 +-
 src/lib/util/pyunittests/Makefile.am           |    2 +-
 src/lib/util/tests/Makefile.am                 |    2 +-
 src/lib/util/unittests/Makefile.am             |    2 +-
 tests/tools/badpacket/Makefile.am              |    2 +-
 tests/tools/badpacket/tests/Makefile.am        |    2 +-
 83 files changed, 6272 insertions(+), 1035 deletions(-)
 create mode 100644 doc/guide/bind10-guide.txt
 delete mode 100644 src/bin/dhcp6/dhcp6.h
 delete mode 100644 src/bin/dhcp6/pkt6.cc
 delete mode 100644 src/bin/dhcp6/pkt6.h
 delete mode 100644 src/bin/dhcp6/tests/pkt6_unittest.cc
 create mode 100644 src/lib/dhcp/Makefile.am
 create mode 100644 src/lib/dhcp/README
 create mode 100644 src/lib/dhcp/dhcp6.h
 create mode 100644 src/lib/dhcp/libdhcp.cc
 create mode 100644 src/lib/dhcp/libdhcp.h
 create mode 100644 src/lib/dhcp/option.cc
 create mode 100644 src/lib/dhcp/option.h
 create mode 100644 src/lib/dhcp/option6_addrlst.cc
 create mode 100644 src/lib/dhcp/option6_addrlst.h
 create mode 100644 src/lib/dhcp/option6_ia.cc
 create mode 100644 src/lib/dhcp/option6_ia.h
 create mode 100644 src/lib/dhcp/option6_iaaddr.cc
 create mode 100644 src/lib/dhcp/option6_iaaddr.h
 create mode 100644 src/lib/dhcp/pkt6.cc
 create mode 100644 src/lib/dhcp/pkt6.h
 create mode 100644 src/lib/dhcp/tests/Makefile.am
 create mode 100644 src/lib/dhcp/tests/libdhcp_unittest.cc
 create mode 100644 src/lib/dhcp/tests/option6_addrlst_unittest.cc
 create mode 100644 src/lib/dhcp/tests/option6_ia_unittest.cc
 create mode 100644 src/lib/dhcp/tests/option6_iaaddr_unittest.cc
 create mode 100644 src/lib/dhcp/tests/option_unittest.cc
 create mode 100644 src/lib/dhcp/tests/pkt6_unittest.cc
 create mode 100644 src/lib/dhcp/tests/run_unittests.cc

-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index 2db865e..76e29bf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+301     [func]      stephen
+	Add system test for IXFR over TCP.
+	(Trac #1213, git 68ee3818bcbecebf3e6789e81ea79d551a4ff3e8)
+
+300.	[func]*		tomek
+	libdhcp: DHCP packet library was implemented. Currently it handles
+	packet reception, option parsing, option generation and output
+	packet building. Generic and specialized classes for several
+	DHCPv6 options (IA_NA, IAADDR, address-list) are available. A
+	simple code was added that leverages libdhcp. It is a skeleton
+	DHCPv6 server. It receives incoming SOLICIT and REQUEST messages
+	and responds with proper ADVERTISE and REPLY. Note that since
+	LeaseManager is not implemented, server assigns the same
+	hardcoded lease for every client. This change removes existing
+	DHCPv6 echo server as it was only a proof of concept code.
+	(Trac #1186, git 67ea6de047d4dbd63c25fe7f03f5d5cc2452ad7d)
+
+299.	[build]		jreed
+	Do not install the libfake_session, libtestutils, or libbench
+	libraries. They are used by tests within the source tree.
+	Convert all test-related makefiles to build test code at
+	regular make time to better work with test-driven development.
+	This reverts some of #1901. (The tests are ran using "make
+	check".)
+	(Trac #1286, git cee641fd3d12341d6bfce5a6fbd913e3aebc1e8e)
+
+bind10-devel-20111014 released on October 14, 2011
+
+298.	[doc]		jreed
+	Shorten README. Include plain text format of the Guide.
+	(git d1897d3, git 337198f)
+
 297.	[func]		dvv
 	Implement the SPF rrtype according to RFC4408.
 	(Trac #1140, git 146934075349f94ee27f23bf9ff01711b94e369e)
@@ -23,7 +55,7 @@
 	how to configure it and operational notes.
 	(Trac #1212, multiple git merges)
 
-293.    [func]*		tomek
+293.	[func]*		tomek
 	b10-dhcp6: Implemented DHCPv6 echo server. It joins DHCPv6
 	multicast groups and listens to incoming DHCPv6 client messages.
 	Received messages are then echoed back to clients. This
@@ -37,12 +69,13 @@
 	Implement the DLV rrtype according to RFC4431.
 	(Trac #1144, git d267c0511a07c41cd92e3b0b9ee9bf693743a7cf)
 
-291.    [func]          naokikambe
+291.	[func]		naokikambe
 	Statistics items are specified by each module's spec file.
 	Stats module can read these through the config manager. Stats
 	module and stats httpd report statistics data and statistics
 	schema by each module via both bindctl and HTTP/XML.
-	(Trac #928,#929,#930,#1175, git 054699635affd9c9ecbe7a108d880829f3ba229e)
+	(Trac #928,#929,#930,#1175,
+	git 054699635affd9c9ecbe7a108d880829f3ba229e)
 
 290.	[func]		jinmei
 	libdns++/pydnspp: added an option parameter to the "from wire"
@@ -54,7 +87,7 @@
 
 289.	[func]*		jinmei
 	b10-xfrout: ACLs for xfrout can now be configured per zone basis.
-	A per zone ACl is part of a more general zone configuration.  A
+	A per zone ACL is part of a more general zone configuration.  A
 	quick example for configuring an ACL for zone "example.com" that
 	rejects any transfer request for that zone is as follows:
 	> config add Xfrout/zone_config
@@ -70,7 +103,7 @@
 	configuration.
 	(Trac #1165, git 698176eccd5d55759fe9448b2c249717c932ac31)
 
-288.    [bug]		stephen
+288.	[bug]		stephen
 	Fixed problem whereby the order in which component files appeared in
 	rdataclass.cc was system dependent, leading to problems on some
 	systems where data types were used before the header file in which
@@ -85,7 +118,7 @@
 	python files from the common directly (such as "site-packages").
 	(Trac #1101, git 0eb576518f81c3758c7dbaa2522bd8302b1836b3)
 
-286.    [func]		ocean
+286.	[func]		ocean
 	libdns++: Implement the HINFO rrtype support according to RFC1034,
 	and RFC1035.
 	(Trac #1112, git 12d62d54d33fbb1572a1aa3089b0d547d02924aa)
@@ -101,14 +134,14 @@
 	log a warning and try to do zone transfer for them.
 	(Trac #1153, git 0a39659638fc68f60b95b102968d7d0ad75443ea)
 
-283.    [bug]		zhanglikun
+283.	[bug]		zhanglikun
 	Make stats and boss processes wait for answer messages from each
 	other in block mode to avoid orphan answer messages, add an internal
 	command "getstats" to boss process for getting statistics data from
 	boss.
 	(Trac #519, git 67d8e93028e014f644868fede3570abb28e5fb43)
 
-282.    [func]		ocean
+282.	[func]		ocean
 	libdns++: Implement the NAPTR rrtype according to RFC2915,
 	RFC2168 and RFC3403.
 	(Trac #1130, git 01d8d0f13289ecdf9996d6d5d26ac0d43e30549c)
diff --git a/README b/README
index 4b84a88..99e2ece 100644
--- a/README
+++ b/README
@@ -1,3 +1,4 @@
+
 This is the source for the development version of BIND 10.
 
 BIND is the popular implementation of a DNS server, developer
@@ -11,7 +12,7 @@ interfaces. Nevertheless it is ready to use now for testing the
 new BIND 10 infrastructure ideas. The Year 3 goals of the five
 year plan are described here:
 
-	http://bind10.isc.org/wiki/Year3Goals
+        http://bind10.isc.org/wiki/Year3Goals
 
 This release includes the bind10 master process, b10-msgq message
 bus, b10-auth authoritative DNS server (with SQLite3 and in-memory
@@ -21,12 +22,15 @@ AXFR inbound service, b10-xfrout outgoing AXFR service, b10-zonemgr
 secondary manager, b10-stats statistics collection and reporting
 daemon, b10-stats-httpd for HTTP access to XML-formatted stats,
 b10-host DNS lookup utility, and a new libdns++ library for C++
-with a python wrapper.
+with a python wrapper. BIND 10 also provides an experimental DHCPv6
+echo server, b10-dhcp6.
 
-Documentation is included and also available via the BIND 10
-website at http://bind10.isc.org/
+Documentation is included with the source. See doc/guide/bind10-guide.txt
+(or bind10-guide.html) for installation instructions.  The
+documentation is also available via the BIND 10 website at
+http://bind10.isc.org/
 
-The latest released source may be downloaded from:
+The latest released source tar file may be downloaded from:
 
         ftp://ftp.isc.org/isc/bind10/
 
@@ -40,15 +44,11 @@ Bugs may be reported as tickets via the developers website:
 
         http://bind10.isc.org/
 
-BUILDING
-
-See the Guide for detailed installation directions at
-doc/guide/bind10-guide.html.
-
-Simple build instructions:
+Simple build and installation instructions:
 
   ./configure
   make
+  make install
 
 If building from Git repository, run:
 
@@ -56,197 +56,11 @@ If building from Git repository, run:
 
 before running ./configure
 
-Requires autoconf 2.59 or newer.
-
-Use automake-1.11 or better for working Python 3.1 tests.
-Alternatively, you could manually specify an absolute path to python
-executable by the --with-pythonpath option of the configure script,
-e.g.,
-% ./configure --with-pythonpath=/usr/local/bin/python3.1
-
-Operating-System specific tips:
-
-- FreeBSD
-  You may need to install a python binding for sqlite3 by hand.
-  A sample procedure is as follows:
-  - add the following to /etc/make.conf
-    PYTHON_VERSION=3.1
-  - build and install the python binding from ports, assuming the top
-    directory of the ports system is /usr/ports
-  % cd /usr/ports/databases/py-sqlite3/
-  % make
-  % sudo make install
-
-INSTALLATION
+See the Guide for detailed installation directions at
+doc/guide/bind10-guide.txt.
 
-Install with:
+For operating system specific tips see the wiki at:
 
-  make install
+       http://bind10.isc.org/wiki/SystemSpecificNotes
 
-TESTS
-
-The tests use the googletests framework for C++. It is available
-from http://code.google.com/p/googletest/.  To enable the tests,
-configure BIND 10 with: 
-
-  ./configure --with-gtest
-
-Then run "make check" to run these tests.
-
-TEST COVERAGE
-
-Code coverage reports may be generated using make. These are
-based on running on the unit tests. The resulting reports are placed
-in coverage-cpp-html and coverage-python-html directories for C++
-and Python, respectively.
-
-The code coverage report for the C++ tests uses LCOV. It is available
-from http://ltp.sourceforge.net/. To generate the HTML report,
-first configure BIND 10 with:
- 
-  ./configure --with-lcov
-
-The code coverage report for the Python tests uses coverage.py (aka
-pycoverage). It is available from http://nedbatchelder.com/code/coverage/.
-To generate the HTML report, first configure BIND 10 with:
-
-  ./configure --with-pycoverage
-
-Doing code coverage tests:
-
-  make coverage
-	Does the clean, perform, and report targets for C++ and Python.
-
-  make clean-coverage
-	Zeroes the code coverage counters and removes the HTML reports
-	for C++ and Python.
-
-  make perform-coverage
-	Runs the C++ (using the googletests framework) and Python
-	tests.
-
-  make report-coverage
-	Generates the coverage reports in HTML for C++ and Python.
-
-  make clean-cpp-coverage
-	Zeroes the code coverage counters and removes the HTML report
-	for the C++ tests.
-
-  make clean-python-coverage
-	Zeroes the code coverage counters and removes the HTML report
-	for the Python tests.
-
-  make report-cpp-coverage
-	Generates the coverage report in HTML for C++, excluding
-	some unrelated headers.  The HTML reports are placed in a
-	directory called coverage-cpp-html/.
-
-  make report-python-coverage
-	Generates the coverage report in HTML for Python. The HTML
-	reports are placed in a directory called coverage-python-html/.
-
-DEVELOPERS
-
-The generated run_*.sh scripts available in the src/bin directories
-are for running the code using the source tree.
-
-RUNNING
-
-You can start the BIND 10 processes by running bind10 which is
-installed to the sbin directory under the installation prefix.
-The default location is:
-
-  /usr/local/sbin/bind10
-
-For development work, you can also run the bind10 services from the
-source tree:
-
- ./src/bin/bind10/run_bind10.sh 
-
-(Which will use the modules and configurations also from the source
-tree.)
-
-CONFIGURATION
-
-Commands can be given through the bindctl tool.
-
-The server must be running for bindctl to work.
-
-The following configuration commands are available
-
-help: show the different command modules
-<module> help: show the commands for module
-<module> <command> help: show info for the command
-
-
-config show [identifier]: Show the currently set values. If no identifier is
-                          given, the current location is used. If a config
-                          option is a list or a map, the value is not
-                          shown directly, but must be requested separately.
-config go [identifier]:   Go to the given location within the configuration.
-config set [identifier] <value>: Set a configuration value.
-config unset [identifier]: Remove a value (reverts to default if the option
-                           is mandatory).
-config add [identifier] <value>: add a value to a list
-config remove [identifier] <value>: remove a value from a list 
-config revert:	Revert all changes that have not been committed
-config commit: Commit all changes
-config diff: Show the changes that have not been committed yet
-
-
-EXAMPLE SESSION
-
-~> bindctl
-["login success "] login as root
-> help
-BindCtl, verstion 0.1
-usage: <module name> <command name> [param1 = value1 [, param2 = value2]]
-Type Tab character to get the hint of module/command/paramters.
-Type "help(? h)" for help on bindctl.
-Type "<module_name> help" for help on the specific module.
-Type "<module_name> <command_name> help" for help on the specific command.
-
-Available module names: 
-	 help 	Get help for bindctl
-	 config 	Configuration commands
-	 Xfrin 	same here
-	 Auth 	same here
-	 Boss 	same here
-> config help
-Module  config 	Configuration commands 
-Available commands:
-	 help 	(Get help for module)
-	 show 	(Show configuration)
-	 add 	(Add entry to configuration list)
-	 remove 	(Remove entry from configuration list)
-	 set 	(Set a configuration value)
-	 unset 	(Unset a configuration value)
-	 diff 	(Show all local changes)
-	 revert 	(Revert all local changes)
-	 commit 	(Commit all local changes)
-	 go 	(Go to a specific configuration part)
-> config show
-Xfrin/	module	
-Auth/	module	
-Boss/	module	
-> config show Xfrin
-transfers_in:	10	integer	
-> config go Auth
-/Auth> config show
-database_file:	None	string	
-/Auth> config set database_file /tmp/bind10_zones.db
-/Auth> config commit
-/Auth> config go /
-> config show Auth/
-database_file:	/tmp/bind10_zones.db	string	
-> config diff
-{}
-> config set Auth/foobar
-Error: missing identifier or value
-> config set Auth/database_file foobar
-> config diff
-{'Auth': {'database_file': 'foobar'}}
-> config revert
-> config diff
-{}
-> quit
+Please see the wiki and the doc/ directory for various documentation.
diff --git a/configure.ac b/configure.ac
index 664ce48..d14395c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -872,6 +872,8 @@ AC_CONFIG_FILES([Makefile
                  src/lib/dns/python/Makefile
                  src/lib/dns/python/tests/Makefile
                  src/lib/dns/benchmarks/Makefile
+                 src/lib/dhcp/Makefile
+                 src/lib/dhcp/tests/Makefile
                  src/lib/exceptions/Makefile
                  src/lib/exceptions/tests/Makefile
                  src/lib/datasrc/Makefile
diff --git a/doc/Doxyfile b/doc/Doxyfile
index 8be9098..ee5aaf8 100644
--- a/doc/Doxyfile
+++ b/doc/Doxyfile
@@ -574,7 +574,7 @@ INPUT                  = ../src/lib/exceptions ../src/lib/cc \
     ../src/lib/log/compiler ../src/lib/asiolink/ ../src/lib/nsas \
     ../src/lib/testutils ../src/lib/cache ../src/lib/server_common/ \
     ../src/bin/sockcreator/ ../src/lib/util/ \
-    ../src/lib/resolve ../src/lib/acl ../src/bin/dhcp6
+    ../src/lib/resolve ../src/lib/acl ../src/bin/dhcp6 ../src/lib/dhcp
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
diff --git a/doc/guide/Makefile.am b/doc/guide/Makefile.am
index c84ad06..239f235 100644
--- a/doc/guide/Makefile.am
+++ b/doc/guide/Makefile.am
@@ -1,5 +1,5 @@
 EXTRA_DIST = bind10-guide.css
-EXTRA_DIST += bind10-guide.xml bind10-guide.html
+EXTRA_DIST += bind10-guide.xml bind10-guide.html bind10-guide.txt
 EXTRA_DIST += bind10-messages.xml bind10-messages.html
 
 # This is not a "man" manual, but reuse this for now for docbook.
@@ -15,6 +15,11 @@ bind10-guide.html: bind10-guide.xml
 		http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl \
 		$(srcdir)/bind10-guide.xml
 
+HTML2TXT = elinks -dump -no-numbering -no-references
+
+bind10-guide.txt: bind10-guide.html
+	$(HTML2TXT) $(srcdir)/bind10-guide.html > $@
+
 bind10-messages.html: bind10-messages.xml
 	xsltproc --novalid --xinclude --nonet \
 		--path $(top_builddir)/doc \
diff --git a/doc/guide/bind10-guide.html b/doc/guide/bind10-guide.html
index 1070a2e..97ffb84 100644
--- a/doc/guide/bind10-guide.html
+++ b/doc/guide/bind10-guide.html
@@ -1,12 +1,14 @@
-<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>BIND 10 Guide</title><link rel="stylesheet" href="./bind10-guide.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.75.2"><meta name="description" content="BIND 10 is a Domain Name System (DNS) suite managed by Internet Systems Consortium (ISC). It includes DNS libraries and modular components for controlling authoritative and recursive DNS servers. This is the reference guide for BIND 10 version 20110809. The most up-to-date version of this document, along with other documents for BIND 10, can be found at ."></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" title="BIND 10 Guide"><div class="titlepage"><div><div><h1 class="title"><a name="id1168229460045"></a>BIND 10 Guide</h1></div><div><h2 class="subtitle">Administrator Reference for BIND 10</h2></div><div><p class="releaseinfo">This is the referenc
 e guide for BIND 10 version
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>BIND 10 Guide</title><link rel="stylesheet" href="./bind10-guide.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.75.2"><meta name="description" content="BIND 10 is a Domain Name System (DNS) suite managed by Internet Systems Consortium (ISC). It includes DNS libraries and modular components for controlling authoritative and recursive DNS servers. This is the reference guide for BIND 10 version 20110809. The most up-to-date version of this document (in PDF, HTML, and plain text formats), along with other documents for BIND 10, can be found at ."></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" title="BIND 10 Guide"><div class="titlepage"><div><div><h1 class="title"><a name="id1168229451102"></a>BIND 10 Guide</h1></div><div><h2 class="subtitle">Administrator Reference for BIND 10</h2></div><div><p c
 lass="releaseinfo">This is the reference guide for BIND 10 version
         20110809.</p></div><div><p class="copyright">Copyright © 2010-2011 Internet Systems Consortium, Inc.</p></div><div><div class="abstract" title="Abstract"><p class="title"><b>Abstract</b></p><p>BIND 10 is a Domain Name System (DNS) suite managed by
 	Internet Systems Consortium (ISC). It includes DNS libraries
 	and modular components for controlling authoritative and
 	recursive DNS servers.
       </p><p>
         This is the reference guide for BIND 10 version 20110809.
-	The most up-to-date version of this document, along with
-	other documents for BIND 10, can be found at <a class="ulink" href="http://bind10.isc.org/docs" target="_top">http://bind10.isc.org/docs</a>.  </p></div></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="chapter"><a href="#intro">1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229460181">Supported Platforms</a></span></dt><dt><span class="section"><a href="#id1168229460208">Required Software</a></span></dt><dt><span class="section"><a href="#starting_stopping">Starting and Stopping the Server</a></span></dt><dt><span class="section"><a href="#managing_once_running">Managing BIND 10</a></span></dt></dl></dd><dt><span class="chapter"><a href="#installation">2. Installation</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229445988">Building Requirements</a></span></dt><dt><span class="section"><a href="#quickstart">Quick start</a></span></dt><dt><span class="section"><a href="#install">In
 stallation from source</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229446178">Download Tar File</a></span></dt><dt><span class="section"><a href="#id1168229446197">Retrieve from Git</a></span></dt><dt><span class="section"><a href="#id1168229446258">Configure before the build</a></span></dt><dt><span class="section"><a href="#id1168229446356">Build</a></span></dt><dt><span class="section"><a href="#id1168229446371">Install</a></span></dt><dt><span class="section"><a href="#id1168229446394">Install Hierarchy</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#bind10">3. Starting BIND10 with <span class="command"><strong>bind10</strong></span></a></span></dt><dd><dl><dt><span class="section"><a href="#start">Starting BIND 10</a></span></dt></dl></dd><dt><span class="chapter"><a href="#msgq">4. Command channel</a></span></dt><dt><span class="chapter"><a href="#cfgmgr">5. Configuration manager</a></span></dt><dt><span class="chapter"><a hr
 ef="#cmdctl">6. Remote control daemon</a></span></dt><dd><dl><dt><span class="section"><a href="#cmdctl.spec">Configuration specification for b10-cmdctl</a></span></dt></dl></dd><dt><span class="chapter"><a href="#bindctl">7. Control and configure user interface</a></span></dt><dt><span class="chapter"><a href="#authserver">8. Authoritative Server</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229446979">Server Configurations</a></span></dt><dt><span class="section"><a href="#id1168229447044">Data Source Backends</a></span></dt><dt><span class="section"><a href="#id1168229447074">Loading Master Zones Files</a></span></dt></dl></dd><dt><span class="chapter"><a href="#xfrin">9. Incoming Zone Transfers</a></span></dt><dt><span class="chapter"><a href="#xfrout">10. Outbound Zone Transfers</a></span></dt><dt><span class="chapter"><a href="#zonemgr">11. Secondary Manager</a></span></dt><dt><span class="chapter"><a href="#resolverserver">12. Recursive Name Server<
 /a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229447556">Access Control</a></span></dt><dt><span class="section"><a href="#id1168229447671">Forwarding</a></span></dt></dl></dd><dt><span class="chapter"><a href="#statistics">13. Statistics</a></span></dt><dt><span class="chapter"><a href="#logging">14. Logging</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229447788">Logging configuration</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229447799">Loggers</a></span></dt><dt><span class="section"><a href="#id1168229448040">Output Options</a></span></dt><dt><span class="section"><a href="#id1168229448215">Example session</a></span></dt></dl></dd><dt><span class="section"><a href="#id1168229448428">Logging Message Format</a></span></dt></dl></dd></dl></div><div class="chapter" title="Chapter 1. Introduction"><div class="titlepage"><div><div><h2 class="title"><a name="intro"></a>Chapter 1. Introduction</h2></div></div></div><di
 v class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168229460181">Supported Platforms</a></span></dt><dt><span class="section"><a href="#id1168229460208">Required Software</a></span></dt><dt><span class="section"><a href="#starting_stopping">Starting and Stopping the Server</a></span></dt><dt><span class="section"><a href="#managing_once_running">Managing BIND 10</a></span></dt></dl></div><p>
+	The most up-to-date version of this document (in PDF, HTML,
+	and plain text formats), along with other documents for
+	BIND 10, can be found at <a class="ulink" href="http://bind10.isc.org/docs" target="_top">http://bind10.isc.org/docs</a>.
+	</p></div></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="chapter"><a href="#intro">1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229451238">Supported Platforms</a></span></dt><dt><span class="section"><a href="#id1168229451265">Required Software</a></span></dt><dt><span class="section"><a href="#starting_stopping">Starting and Stopping the Server</a></span></dt><dt><span class="section"><a href="#managing_once_running">Managing BIND 10</a></span></dt></dl></dd><dt><span class="chapter"><a href="#installation">2. Installation</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229436567">Building Requirements</a></span></dt><dt><span class="section"><a href="#quickstart">Quick start</a></span></dt><dt><span class="section"><a href="#install">Installation from source</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229436859">Download Tar File</a></span></dt><dt><span c
 lass="section"><a href="#id1168229436878">Retrieve from Git</a></span></dt><dt><span class="section"><a href="#id1168229436939">Configure before the build</a></span></dt><dt><span class="section"><a href="#id1168229437037">Build</a></span></dt><dt><span class="section"><a href="#id1168229437052">Install</a></span></dt><dt><span class="section"><a href="#id1168229437076">Install Hierarchy</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#bind10">3. Starting BIND10 with <span class="command"><strong>bind10</strong></span></a></span></dt><dd><dl><dt><span class="section"><a href="#start">Starting BIND 10</a></span></dt></dl></dd><dt><span class="chapter"><a href="#msgq">4. Command channel</a></span></dt><dt><span class="chapter"><a href="#cfgmgr">5. Configuration manager</a></span></dt><dt><span class="chapter"><a href="#cmdctl">6. Remote control daemon</a></span></dt><dd><dl><dt><span class="section"><a href="#cmdctl.spec">Configuration specification for b
 10-cmdctl</a></span></dt></dl></dd><dt><span class="chapter"><a href="#bindctl">7. Control and configure user interface</a></span></dt><dt><span class="chapter"><a href="#authserver">8. Authoritative Server</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229437660">Server Configurations</a></span></dt><dt><span class="section"><a href="#id1168229437725">Data Source Backends</a></span></dt><dt><span class="section"><a href="#id1168229437755">Loading Master Zones Files</a></span></dt></dl></dd><dt><span class="chapter"><a href="#xfrin">9. Incoming Zone Transfers</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229437989">Configuration for Incoming Zone Transfers</a></span></dt><dt><span class="section"><a href="#id1168229438027">Enabling IXFR</a></span></dt><dt><span class="section"><a href="#id1168229438069">Trigger an Incoming Zone Transfer Manually</a></span></dt></dl></dd><dt><span class="chapter"><a href="#xfrout">10. Outbound Zone Transfe
 rs</a></span></dt><dt><span class="chapter"><a href="#zonemgr">11. Secondary Manager</a></span></dt><dt><span class="chapter"><a href="#resolverserver">12. Recursive Name Server</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229438327">Access Control</a></span></dt><dt><span class="section"><a href="#id1168229438512">Forwarding</a></span></dt></dl></dd><dt><span class="chapter"><a href="#statistics">13. Statistics</a></span></dt><dt><span class="chapter"><a href="#logging">14. Logging</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229438628">Logging configuration</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229438638">Loggers</a></span></dt><dt><span class="section"><a href="#id1168229439154">Output Options</a></span></dt><dt><span class="section"><a href="#id1168229439328">Example session</a></span></dt></dl></dd><dt><span class="section"><a href="#id1168229439609">Logging Message Format</a></span></dt></dl></dd></dl><
 /div><div class="chapter" title="Chapter 1. Introduction"><div class="titlepage"><div><div><h2 class="title"><a name="intro"></a>Chapter 1. Introduction</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168229451238">Supported Platforms</a></span></dt><dt><span class="section"><a href="#id1168229451265">Required Software</a></span></dt><dt><span class="section"><a href="#starting_stopping">Starting and Stopping the Server</a></span></dt><dt><span class="section"><a href="#managing_once_running">Managing BIND 10</a></span></dt></dl></div><p>
       BIND is the popular implementation of a DNS server, developer
       interfaces, and DNS tools.
       BIND 10 is a rewrite of BIND 9.  BIND 10 is written in C++ and Python
@@ -18,7 +20,7 @@
         BIND 10 provides a EDNS0- and DNSSEC-capable
         authoritative DNS server and a caching recursive name server
         which also provides forwarding.
-      </p></div><div class="section" title="Supported Platforms"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229460181"></a>Supported Platforms</h2></div></div></div><p>
+      </p></div><div class="section" title="Supported Platforms"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229451238"></a>Supported Platforms</h2></div></div></div><p>
   BIND 10 builds have been tested on Debian GNU/Linux 5,
   Ubuntu 9.10, NetBSD 5, Solaris 10, FreeBSD 7 and 8, and CentOS
   Linux 5.3.
@@ -28,7 +30,7 @@
 
         It is planned for BIND 10 to build, install and run on
         Windows and standard Unix-type platforms.
-      </p></div><div class="section" title="Required Software"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229460208"></a>Required Software</h2></div></div></div><p>
+      </p></div><div class="section" title="Required Software"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229451265"></a>Required Software</h2></div></div></div><p>
         BIND 10 requires Python 3.1.  Later versions may work, but Python
         3.1 is the minimum version which will work.
       </p><p>
@@ -138,7 +140,7 @@
       and, of course, DNS. These include detailed developer
       documentation and code examples.
 
-    </p></div><div class="chapter" title="Chapter 2. Installation"><div class="titlepage"><div><div><h2 class="title"><a name="installation"></a>Chapter 2. Installation</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168229445988">Building Requirements</a></span></dt><dt><span class="section"><a href="#quickstart">Quick start</a></span></dt><dt><span class="section"><a href="#install">Installation from source</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229446178">Download Tar File</a></span></dt><dt><span class="section"><a href="#id1168229446197">Retrieve from Git</a></span></dt><dt><span class="section"><a href="#id1168229446258">Configure before the build</a></span></dt><dt><span class="section"><a href="#id1168229446356">Build</a></span></dt><dt><span class="section"><a href="#id1168229446371">Install</a></span></dt><dt><span class="section"><a href="#id1168229446394">Install Hierarchy<
 /a></span></dt></dl></dd></dl></div><div class="section" title="Building Requirements"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229445988"></a>Building Requirements</h2></div></div></div><p>
+    </p></div><div class="chapter" title="Chapter 2. Installation"><div class="titlepage"><div><div><h2 class="title"><a name="installation"></a>Chapter 2. Installation</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168229436567">Building Requirements</a></span></dt><dt><span class="section"><a href="#quickstart">Quick start</a></span></dt><dt><span class="section"><a href="#install">Installation from source</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229436859">Download Tar File</a></span></dt><dt><span class="section"><a href="#id1168229436878">Retrieve from Git</a></span></dt><dt><span class="section"><a href="#id1168229436939">Configure before the build</a></span></dt><dt><span class="section"><a href="#id1168229437037">Build</a></span></dt><dt><span class="section"><a href="#id1168229437052">Install</a></span></dt><dt><span class="section"><a href="#id1168229437076">Install Hierarchy<
 /a></span></dt></dl></dd></dl></div><div class="section" title="Building Requirements"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229436567"></a>Building Requirements</h2></div></div></div><p>
           In addition to the run-time requirements, building BIND 10
           from source code requires various development include headers.
         </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
@@ -202,14 +204,14 @@
         the Git code revision control system or as a downloadable
         tar file. It may also be available in pre-compiled ready-to-use
         packages from operating system vendors.
-      </p><div class="section" title="Download Tar File"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229446178"></a>Download Tar File</h3></div></div></div><p>
+      </p><div class="section" title="Download Tar File"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229436859"></a>Download Tar File</h3></div></div></div><p>
           Downloading a release tar file is the recommended method to
           obtain the source code.
         </p><p>
           The BIND 10 releases are available as tar file downloads from
           <a class="ulink" href="ftp://ftp.isc.org/isc/bind10/" target="_top">ftp://ftp.isc.org/isc/bind10/</a>.
           Periodic development snapshots may also be available.
-        </p></div><div class="section" title="Retrieve from Git"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229446197"></a>Retrieve from Git</h3></div></div></div><p>
+        </p></div><div class="section" title="Retrieve from Git"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229436878"></a>Retrieve from Git</h3></div></div></div><p>
           Downloading this "bleeding edge" code is recommended only for
           developers or advanced users.  Using development code in a production
           environment is not recommended.
@@ -243,7 +245,7 @@
           <span class="command"><strong>autoheader</strong></span>,
           <span class="command"><strong>automake</strong></span>,
           and related commands.
-        </p></div><div class="section" title="Configure before the build"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229446258"></a>Configure before the build</h3></div></div></div><p>
+        </p></div><div class="section" title="Configure before the build"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229436939"></a>Configure before the build</h3></div></div></div><p>
           BIND 10 uses the GNU Build System to discover build environment
           details.
           To generate the makefiles using the defaults, simply run:
@@ -274,16 +276,16 @@
         </p><p>
           If the configure fails, it may be due to missing or old
           dependencies.
-        </p></div><div class="section" title="Build"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229446356"></a>Build</h3></div></div></div><p>
+        </p></div><div class="section" title="Build"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229437037"></a>Build</h3></div></div></div><p>
     After the configure step is complete, to build the executables
     from the C++ code and prepare the Python scripts, run:
 
           </p><pre class="screen">$ <strong class="userinput"><code>make</code></strong></pre><p>
-        </p></div><div class="section" title="Install"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229446371"></a>Install</h3></div></div></div><p>
+        </p></div><div class="section" title="Install"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229437052"></a>Install</h3></div></div></div><p>
           To install the BIND 10 executables, support files,
           and documentation, run:
           </p><pre class="screen">$ <strong class="userinput"><code>make install</code></strong></pre><p>
-        </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>The install step may require superuser privileges.</p></div></div><div class="section" title="Install Hierarchy"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229446394"></a>Install Hierarchy</h3></div></div></div><p>
+        </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>The install step may require superuser privileges.</p></div></div><div class="section" title="Install Hierarchy"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229437076"></a>Install Hierarchy</h3></div></div></div><p>
           The following is the layout of the complete BIND 10 installation:
           </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
                 <code class="filename">bin/</code> —
@@ -505,12 +507,12 @@ shutdown
       the details and relays (over a <span class="command"><strong>b10-msgq</strong></span> command
       channel) the configuration on to the specified module.
     </p><p>
-    </p></div><div class="chapter" title="Chapter 8. Authoritative Server"><div class="titlepage"><div><div><h2 class="title"><a name="authserver"></a>Chapter 8. Authoritative Server</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168229446979">Server Configurations</a></span></dt><dt><span class="section"><a href="#id1168229447044">Data Source Backends</a></span></dt><dt><span class="section"><a href="#id1168229447074">Loading Master Zones Files</a></span></dt></dl></div><p>
+    </p></div><div class="chapter" title="Chapter 8. Authoritative Server"><div class="titlepage"><div><div><h2 class="title"><a name="authserver"></a>Chapter 8. Authoritative Server</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168229437660">Server Configurations</a></span></dt><dt><span class="section"><a href="#id1168229437725">Data Source Backends</a></span></dt><dt><span class="section"><a href="#id1168229437755">Loading Master Zones Files</a></span></dt></dl></div><p>
       The <span class="command"><strong>b10-auth</strong></span> is the authoritative DNS server.
       It supports EDNS0 and DNSSEC. It supports IPv6.
       Normally it is started by the <span class="command"><strong>bind10</strong></span> master
       process.
-    </p><div class="section" title="Server Configurations"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229446979"></a>Server Configurations</h2></div></div></div><p>
+    </p><div class="section" title="Server Configurations"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229437660"></a>Server Configurations</h2></div></div></div><p>
         <span class="command"><strong>b10-auth</strong></span> is configured via the
         <span class="command"><strong>b10-cfgmgr</strong></span> configuration manager.
         The module name is <span class="quote">“<span class="quote">Auth</span>”</span>.
@@ -530,7 +532,7 @@ This may be a temporary setting until then.
         </p><div class="variablelist"><dl><dt><span class="term">shutdown</span></dt><dd>Stop the authoritative DNS server.
               </dd></dl></div><p>
 
-      </p></div><div class="section" title="Data Source Backends"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229447044"></a>Data Source Backends</h2></div></div></div><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+      </p></div><div class="section" title="Data Source Backends"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229437725"></a>Data Source Backends</h2></div></div></div><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
         For the development prototype release, <span class="command"><strong>b10-auth</strong></span>
         supports a SQLite3 data source backend and in-memory data source
         backend.
@@ -544,7 +546,7 @@ This may be a temporary setting until then.
         The default is <code class="filename">/usr/local/var/</code>.)
   This data file location may be changed by defining the
   <span class="quote">“<span class="quote">database_file</span>”</span> configuration.
-      </p></div><div class="section" title="Loading Master Zones Files"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229447074"></a>Loading Master Zones Files</h2></div></div></div><p>
+      </p></div><div class="section" title="Loading Master Zones Files"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229437755"></a>Loading Master Zones Files</h2></div></div></div><p>
         RFC 1035 style DNS master zone files may imported
         into a BIND 10 data source by using the
         <span class="command"><strong>b10-loadzone</strong></span> utility.
@@ -573,28 +575,69 @@ This may be a temporary setting until then.
         If you reload a zone already existing in the database,
         all records from that prior zone disappear and a whole new set
         appears.
-      </p></div></div><div class="chapter" title="Chapter 9. Incoming Zone Transfers"><div class="titlepage"><div><div><h2 class="title"><a name="xfrin"></a>Chapter 9. Incoming Zone Transfers</h2></div></div></div><p>
+      </p></div></div><div class="chapter" title="Chapter 9. Incoming Zone Transfers"><div class="titlepage"><div><div><h2 class="title"><a name="xfrin"></a>Chapter 9. Incoming Zone Transfers</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168229437989">Configuration for Incoming Zone Transfers</a></span></dt><dt><span class="section"><a href="#id1168229438027">Enabling IXFR</a></span></dt><dt><span class="section"><a href="#id1168229438069">Trigger an Incoming Zone Transfer Manually</a></span></dt></dl></div><p>
       Incoming zones are transferred using the <span class="command"><strong>b10-xfrin</strong></span>
       process which is started by <span class="command"><strong>bind10</strong></span>.
-      When received, the zone is stored in the BIND 10
-      data store, and its records can be served by
+      When received, the zone is stored in the corresponding BIND 10
+      data source, and its records can be served by
       <span class="command"><strong>b10-auth</strong></span>.
       In combination with <span class="command"><strong>b10-zonemgr</strong></span> (for
       automated SOA checks), this allows the BIND 10 server to
       provide <span class="quote">“<span class="quote">secondary</span>”</span> service.
+    </p><p>
+      The <span class="command"><strong>b10-xfrin</strong></span> process supports both AXFR and
+      IXFR.  Due to some implementation limitations of the current
+      development release, however, it only tries AXFR by default,
+      and care should be taken to enable IXFR.
     </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
-     The current development release of BIND 10 only supports
-     AXFR. (IXFR is not supported.)
-
-
-
-    </p></div><p>
-       To manually trigger a zone transfer to retrieve a remote zone,
-       you may use the <span class="command"><strong>bindctl</strong></span> utility.
-       For example, at the <span class="command"><strong>bindctl</strong></span> prompt run:
-
-       </p><pre class="screen">> <strong class="userinput"><code>Xfrin retransfer zone_name="<code class="option">foo.example.org</code>" master=<code class="option">192.0.2.99</code></code></strong></pre><p>
-    </p></div><div class="chapter" title="Chapter 10. Outbound Zone Transfers"><div class="titlepage"><div><div><h2 class="title"><a name="xfrout"></a>Chapter 10. Outbound Zone Transfers</h2></div></div></div><p>
+     In the current development release of BIND 10, incoming zone
+     transfers are only available for SQLite3-based data sources,
+     that is, they don't work for an in-memory data source.
+    </p></div><div class="section" title="Configuration for Incoming Zone Transfers"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229437989"></a>Configuration for Incoming Zone Transfers</h2></div></div></div><p>
+	In practice, you need to specify a list of secondary zones to
+	enable incoming zone transfers for these zones (you can still
+	trigger a zone transfer manually, without a prior configuration
+	(see below)).
+      </p><p>
+	For example, to enable zone transfers for a zone named "example.com"
+	(whose master address is assumed to be 2001:db8::53 here),
+	run the following at the <span class="command"><strong>bindctl</strong></span> prompt:
+
+      </p><pre class="screen">> <strong class="userinput"><code>config add Xfrin/zones</code></strong>
+> <strong class="userinput"><code>config set Xfrin/zones[0]/name "<code class="option">example.com</code>"</code></strong>
+> <strong class="userinput"><code>config set Xfrin/zones[0]/master_addr "<code class="option">2001:db8::53</code>"</code></strong>
+> <strong class="userinput"><code>config commit</code></strong></pre><p>
+
+      (We assume there has been no zone configuration before).
+      </p></div><div class="section" title="Enabling IXFR"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229438027"></a>Enabling IXFR</h2></div></div></div><p>
+        As noted above, <span class="command"><strong>b10-xfrin</strong></span> uses AXFR for
+        zone transfers by default.  To enable IXFR for zone transfers
+        for a particular zone, set the <strong class="userinput"><code>use_ixfr</code></strong>
+        configuration parameter to <strong class="userinput"><code>true</code></strong>.
+        In the above example of configuration sequence, you'll need
+        to add the following before performing <strong class="userinput"><code>commit</code></strong>:
+      </p><pre class="screen">> <strong class="userinput"><code>config set Xfrin/zones[0]/use_ixfr true</code></strong></pre><p>
+      </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+      One reason why IXFR is disabled by default in the current
+      release is because it does not support automatic fallback from IXFR to
+      AXFR when it encounters a primary server that doesn't support
+      outbound IXFR (and, not many existing implementations support
+      it).  Another, related reason is that it does not use AXFR even
+      if it has no knowledge about the zone (like at the very first
+      time the secondary server is set up).  IXFR requires the
+      "current version" of the zone, so obviously it doesn't work
+      in this situation and AXFR is the only workable choice.
+      The current release of <span class="command"><strong>b10-xfrin</strong></span> does not
+      make this selection automatically.
+      These features will be implemented in a near future
+      version, at which point we will enable IXFR by default.
+      </p></div></div><div class="section" title="Trigger an Incoming Zone Transfer Manually"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229438069"></a>Trigger an Incoming Zone Transfer Manually</h2></div></div></div><p>
+	To manually trigger a zone transfer to retrieve a remote zone,
+	you may use the <span class="command"><strong>bindctl</strong></span> utility.
+	For example, at the <span class="command"><strong>bindctl</strong></span> prompt run:
+
+	</p><pre class="screen">> <strong class="userinput"><code>Xfrin retransfer zone_name="<code class="option">foo.example.org</code>" master=<code class="option">192.0.2.99</code></code></strong></pre><p>
+      </p></div></div><div class="chapter" title="Chapter 10. Outbound Zone Transfers"><div class="titlepage"><div><div><h2 class="title"><a name="xfrout"></a>Chapter 10. Outbound Zone Transfers</h2></div></div></div><p>
       The <span class="command"><strong>b10-xfrout</strong></span> process is started by
       <span class="command"><strong>bind10</strong></span>.
       When the <span class="command"><strong>b10-auth</strong></span> authoritative DNS server
@@ -622,7 +665,7 @@ This may be a temporary setting until then.
     </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
      Access control (such as allowing notifies) is not yet provided.
      The primary/secondary service is not yet complete.
-    </p></div></div><div class="chapter" title="Chapter 12. Recursive Name Server"><div class="titlepage"><div><div><h2 class="title"><a name="resolverserver"></a>Chapter 12. Recursive Name Server</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168229447556">Access Control</a></span></dt><dt><span class="section"><a href="#id1168229447671">Forwarding</a></span></dt></dl></div><p>
+    </p></div></div><div class="chapter" title="Chapter 12. Recursive Name Server"><div class="titlepage"><div><div><h2 class="title"><a name="resolverserver"></a>Chapter 12. Recursive Name Server</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168229438327">Access Control</a></span></dt><dt><span class="section"><a href="#id1168229438512">Forwarding</a></span></dt></dl></div><p>
       The <span class="command"><strong>b10-resolver</strong></span> process is started by
       <span class="command"><strong>bind10</strong></span>.
 
@@ -656,7 +699,7 @@ This may be a temporary setting until then.
 </pre><p>
     </p><p>(Replace the <span class="quote">“<span class="quote"><em class="replaceable"><code>2</code></em></span>”</span>
        as needed; run <span class="quote">“<span class="quote"><strong class="userinput"><code>config show
-       Resolver/listen_on</code></strong></span>”</span> if needed.)</p><div class="section" title="Access Control"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229447556"></a>Access Control</h2></div></div></div><p>
+       Resolver/listen_on</code></strong></span>”</span> if needed.)</p><div class="section" title="Access Control"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229438327"></a>Access Control</h2></div></div></div><p>
         By default, the <span class="command"><strong>b10-resolver</strong></span> daemon only accepts
         DNS queries from the localhost (127.0.0.1 and ::1).
         The <code class="option">Resolver/query_acl</code> configuration may
@@ -689,7 +732,7 @@ This may be a temporary setting until then.
 </pre><p>(Replace the <span class="quote">“<span class="quote"><em class="replaceable"><code>2</code></em></span>”</span>
        as needed; run <span class="quote">“<span class="quote"><strong class="userinput"><code>config show
        Resolver/query_acl</code></strong></span>”</span> if needed.)</p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>This prototype access control configuration
-      syntax may be changed.</p></div></div><div class="section" title="Forwarding"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229447671"></a>Forwarding</h2></div></div></div><p>
+      syntax may be changed.</p></div></div><div class="section" title="Forwarding"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229438512"></a>Forwarding</h2></div></div></div><p>
 
         To enable forwarding, the upstream address and port must be
         configured to forward queries to, such as:
@@ -743,7 +786,7 @@ This may be a temporary setting until then.
     }
 }
        </pre><p>
-    </p></div><div class="chapter" title="Chapter 14. Logging"><div class="titlepage"><div><div><h2 class="title"><a name="logging"></a>Chapter 14. Logging</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168229447788">Logging configuration</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229447799">Loggers</a></span></dt><dt><span class="section"><a href="#id1168229448040">Output Options</a></span></dt><dt><span class="section"><a href="#id1168229448215">Example session</a></span></dt></dl></dd><dt><span class="section"><a href="#id1168229448428">Logging Message Format</a></span></dt></dl></div><div class="section" title="Logging configuration"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229447788"></a>Logging configuration</h2></div></div></div><p>
+    </p></div><div class="chapter" title="Chapter 14. Logging"><div class="titlepage"><div><div><h2 class="title"><a name="logging"></a>Chapter 14. Logging</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168229438628">Logging configuration</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168229438638">Loggers</a></span></dt><dt><span class="section"><a href="#id1168229439154">Output Options</a></span></dt><dt><span class="section"><a href="#id1168229439328">Example session</a></span></dt></dl></dd><dt><span class="section"><a href="#id1168229439609">Logging Message Format</a></span></dt></dl></div><div class="section" title="Logging configuration"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229438628"></a>Logging configuration</h2></div></div></div><p>
 
 	The logging system in BIND 10 is configured through the
 	Logging module. All BIND 10 modules will look at the
@@ -752,7 +795,7 @@ This may be a temporary setting until then.
 
 
 
-      </p><div class="section" title="Loggers"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229447799"></a>Loggers</h3></div></div></div><p>
+      </p><div class="section" title="Loggers"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229438638"></a>Loggers</h3></div></div></div><p>
 
 	  Within BIND 10, a message is logged through a component
 	  called a "logger". Different parts of BIND 10 log messages
@@ -773,7 +816,7 @@ This may be a temporary setting until then.
 	  (what to log), and the <code class="option">output_options</code>
 	  (where to log).
 
-        </p><div class="section" title="name (string)"><div class="titlepage"><div><div><h4 class="title"><a name="id1168229447824"></a>name (string)</h4></div></div></div><p>
+        </p><div class="section" title="name (string)"><div class="titlepage"><div><div><h4 class="title"><a name="id1168229438663"></a>name (string)</h4></div></div></div><p>
 	  Each logger in the system has a name, the name being that
 	  of the component using it to log messages. For instance,
 	  if you want to configure logging for the resolver module,
@@ -846,7 +889,7 @@ This may be a temporary setting until then.
 	  <span class="quote">“<span class="quote">Auth.cache</span>”</span> logger will appear in the output
 	  with a logger name of <span class="quote">“<span class="quote">b10-auth.cache</span>”</span>).
 
-        </p></div><div class="section" title="severity (string)"><div class="titlepage"><div><div><h4 class="title"><a name="id1168229447923"></a>severity (string)</h4></div></div></div><p>
+        </p></div><div class="section" title="severity (string)"><div class="titlepage"><div><div><h4 class="title"><a name="id1168229439035"></a>severity (string)</h4></div></div></div><p>
 
           This specifies the category of messages logged.
 	  Each message is logged with an associated severity which
@@ -862,7 +905,7 @@ This may be a temporary setting until then.
 
 
 
-        </p></div><div class="section" title="output_options (list)"><div class="titlepage"><div><div><h4 class="title"><a name="id1168229447973"></a>output_options (list)</h4></div></div></div><p>
+        </p></div><div class="section" title="output_options (list)"><div class="titlepage"><div><div><h4 class="title"><a name="id1168229439086"></a>output_options (list)</h4></div></div></div><p>
 
 	  Each logger can have zero or more
 	  <code class="option">output_options</code>. These specify where log
@@ -872,7 +915,7 @@ This may be a temporary setting until then.
 
           The other options for a logger are:
 
-        </p></div><div class="section" title="debuglevel (integer)"><div class="titlepage"><div><div><h4 class="title"><a name="id1168229447990"></a>debuglevel (integer)</h4></div></div></div><p>
+        </p></div><div class="section" title="debuglevel (integer)"><div class="titlepage"><div><div><h4 class="title"><a name="id1168229439102"></a>debuglevel (integer)</h4></div></div></div><p>
 
 	  When a logger's severity is set to DEBUG, this value
 	  specifies what debug messages should be printed. It ranges
@@ -881,7 +924,7 @@ This may be a temporary setting until then.
 
           If severity for the logger is not DEBUG, this value is ignored.
 
-        </p></div><div class="section" title="additive (true or false)"><div class="titlepage"><div><div><h4 class="title"><a name="id1168229448005"></a>additive (true or false)</h4></div></div></div><p>
+        </p></div><div class="section" title="additive (true or false)"><div class="titlepage"><div><div><h4 class="title"><a name="id1168229439117"></a>additive (true or false)</h4></div></div></div><p>
 
 	  If this is true, the <code class="option">output_options</code> from
 	  the parent will be used. For example, if there are two
@@ -895,18 +938,18 @@ This may be a temporary setting until then.
 
 
 
-      </p></div></div><div class="section" title="Output Options"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229448040"></a>Output Options</h3></div></div></div><p>
+      </p></div></div><div class="section" title="Output Options"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229439154"></a>Output Options</h3></div></div></div><p>
 
 	  The main settings for an output option are the
 	  <code class="option">destination</code> and a value called
 	  <code class="option">output</code>, the meaning of which depends on
 	  the destination that is set.
 
-        </p><div class="section" title="destination (string)"><div class="titlepage"><div><div><h4 class="title"><a name="id1168229448056"></a>destination (string)</h4></div></div></div><p>
+        </p><div class="section" title="destination (string)"><div class="titlepage"><div><div><h4 class="title"><a name="id1168229439169"></a>destination (string)</h4></div></div></div><p>
 
             The destination is the type of output. It can be one of:
 
-          </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> console </li><li class="listitem"> file </li><li class="listitem"> syslog </li></ul></div></div><div class="section" title="output (string)"><div class="titlepage"><div><div><h4 class="title"><a name="id1168229448088"></a>output (string)</h4></div></div></div><p>
+          </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> console </li><li class="listitem"> file </li><li class="listitem"> syslog </li></ul></div></div><div class="section" title="output (string)"><div class="titlepage"><div><div><h4 class="title"><a name="id1168229439201"></a>output (string)</h4></div></div></div><p>
 
 	  Depending on what is set as the output destination, this
 	  value is interpreted as follows:
@@ -928,12 +971,12 @@ This may be a temporary setting until then.
 
           The other options for <code class="option">output_options</code> are:
 
-        </p><div class="section" title="flush (true of false)"><div class="titlepage"><div><div><h5 class="title"><a name="id1168229448172"></a>flush (true of false)</h5></div></div></div><p>
+        </p><div class="section" title="flush (true of false)"><div class="titlepage"><div><div><h5 class="title"><a name="id1168229439286"></a>flush (true of false)</h5></div></div></div><p>
 	    Flush buffers after each log message. Doing this will
 	    reduce performance but will ensure that if the program
 	    terminates abnormally, all messages up to the point of
 	    termination are output.
-          </p></div><div class="section" title="maxsize (integer)"><div class="titlepage"><div><div><h5 class="title"><a name="id1168229448182"></a>maxsize (integer)</h5></div></div></div><p>
+          </p></div><div class="section" title="maxsize (integer)"><div class="titlepage"><div><div><h5 class="title"><a name="id1168229439296"></a>maxsize (integer)</h5></div></div></div><p>
 	    Only relevant when destination is file, this is maximum
 	    file size of output files in bytes. When the maximum
 	    size is reached, the file is renamed and a new file opened.
@@ -942,11 +985,11 @@ This may be a temporary setting until then.
             etc.)
           </p><p>
             If this is 0, no maximum file size is used.
-          </p></div><div class="section" title="maxver (integer)"><div class="titlepage"><div><div><h5 class="title"><a name="id1168229448196"></a>maxver (integer)</h5></div></div></div><p>
+          </p></div><div class="section" title="maxver (integer)"><div class="titlepage"><div><div><h5 class="title"><a name="id1168229439308"></a>maxver (integer)</h5></div></div></div><p>
 	    Maximum number of old log files to keep around when
 	    rolling the output file. Only relevant when
 	    <code class="option">destination</code> is <span class="quote">“<span class="quote">file</span>”</span>.
-          </p></div></div></div><div class="section" title="Example session"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229448215"></a>Example session</h3></div></div></div><p>
+          </p></div></div></div><div class="section" title="Example session"><div class="titlepage"><div><div><h3 class="title"><a name="id1168229439328"></a>Example session</h3></div></div></div><p>
 
 	  In this example we want to set the global logging to
 	  write to the file <code class="filename">/var/log/my_bind10.log</code>,
@@ -1107,7 +1150,7 @@ Logging/loggers[0]/output_options[0]/maxver	8	integer	(modified)
 	  And every module will now be using the values from the
 	  logger named <span class="quote">“<span class="quote">*</span>”</span>.
 
-        </p></div></div><div class="section" title="Logging Message Format"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229448428"></a>Logging Message Format</h2></div></div></div><p>
+        </p></div></div><div class="section" title="Logging Message Format"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168229439609"></a>Logging Message Format</h2></div></div></div><p>
 	  Each message written by BIND 10 to the configured logging
 	  destinations comprises a number of components that identify
 	  the origin of the message and, if the message indicates
diff --git a/doc/guide/bind10-guide.txt b/doc/guide/bind10-guide.txt
new file mode 100644
index 0000000..619d56f
--- /dev/null
+++ b/doc/guide/bind10-guide.txt
@@ -0,0 +1,1201 @@
+                                 BIND 10 Guide
+
+Administrator Reference for BIND 10
+
+   This is the reference guide for BIND 10 version 20110809.
+
+   Copyright (c) 2010-2011 Internet Systems Consortium, Inc.
+
+   Abstract
+
+   BIND 10 is a Domain Name System (DNS) suite managed by Internet Systems
+   Consortium (ISC). It includes DNS libraries and modular components for
+   controlling authoritative and recursive DNS servers.
+
+   This is the reference guide for BIND 10 version 20110809. The most
+   up-to-date version of this document (in PDF, HTML, and plain text
+   formats), along with other documents for BIND 10, can be found at
+   http://bind10.isc.org/docs.
+
+   --------------------------------------------------------------------------
+
+   Table of Contents
+
+   1. Introduction
+
+                Supported Platforms
+
+                Required Software
+
+                Starting and Stopping the Server
+
+                Managing BIND 10
+
+   2. Installation
+
+                Building Requirements
+
+                Quick start
+
+                Installation from source
+
+                             Download Tar File
+
+                             Retrieve from Git
+
+                             Configure before the build
+
+                             Build
+
+                             Install
+
+                             Install Hierarchy
+
+   3. Starting BIND10 with bind10
+
+                Starting BIND 10
+
+   4. Command channel
+
+   5. Configuration manager
+
+   6. Remote control daemon
+
+                Configuration specification for b10-cmdctl
+
+   7. Control and configure user interface
+
+   8. Authoritative Server
+
+                Server Configurations
+
+                Data Source Backends
+
+                Loading Master Zones Files
+
+   9. Incoming Zone Transfers
+
+                Configuration for Incoming Zone Transfers
+
+                Enabling IXFR
+
+                Trigger an Incoming Zone Transfer Manually
+
+   10. Outbound Zone Transfers
+
+   11. Secondary Manager
+
+   12. Recursive Name Server
+
+                Access Control
+
+                Forwarding
+
+   13. Statistics
+
+   14. Logging
+
+                Logging configuration
+
+                             Loggers
+
+                             Output Options
+
+                             Example session
+
+                Logging Message Format
+
+Chapter 1. Introduction
+
+   Table of Contents
+
+   Supported Platforms
+
+   Required Software
+
+   Starting and Stopping the Server
+
+   Managing BIND 10
+
+   BIND is the popular implementation of a DNS server, developer interfaces,
+   and DNS tools. BIND 10 is a rewrite of BIND 9. BIND 10 is written in C++
+   and Python and provides a modular environment for serving and maintaining
+   DNS.
+
+  Note
+
+   This guide covers the experimental prototype of BIND 10 version 20110809.
+
+  Note
+
+   BIND 10 provides a EDNS0- and DNSSEC-capable authoritative DNS server and
+   a caching recursive name server which also provides forwarding.
+
+Supported Platforms
+
+   BIND 10 builds have been tested on Debian GNU/Linux 5, Ubuntu 9.10, NetBSD
+   5, Solaris 10, FreeBSD 7 and 8, and CentOS Linux 5.3. It has been tested
+   on Sparc, i386, and amd64 hardware platforms. It is planned for BIND 10 to
+   build, install and run on Windows and standard Unix-type platforms.
+
+Required Software
+
+   BIND 10 requires Python 3.1. Later versions may work, but Python 3.1 is
+   the minimum version which will work.
+
+   BIND 10 uses the Botan crypto library for C++. It requires at least Botan
+   version 1.8.
+
+   BIND 10 uses the log4cplus C++ logging library. It requires at least
+   log4cplus version 1.0.3.
+
+   The authoritative server requires SQLite 3.3.9 or newer. The b10-xfrin,
+   b10-xfrout, and b10-zonemgr modules require the libpython3 library and the
+   Python _sqlite3.so module.
+
+  Note
+
+   Some operating systems do not provide these dependencies in their default
+   installation nor standard packages collections. You may need to install
+   them separately.
+
+Starting and Stopping the Server
+
+   BIND 10 is modular. Part of this modularity is accomplished using multiple
+   cooperating processes which, together, provide the server functionality.
+   This is a change from the previous generation of BIND software, which used
+   a single process.
+
+   At first, running many different processes may seem confusing. However,
+   these processes are started, stopped, and maintained by a single command,
+   bind10. This command starts a master process which will start other
+   processes as needed. The processes started by the bind10 command have
+   names starting with "b10-", including:
+
+     o b10-msgq -- Message bus daemon. This process coordinates communication
+       between all of the other BIND 10 processes.
+     o b10-auth -- Authoritative DNS server. This process serves DNS
+       requests.
+     o b10-cfgmgr -- Configuration manager. This process maintains all of the
+       configuration for BIND 10.
+     o b10-cmdctl -- Command and control service. This process allows
+       external control of the BIND 10 system.
+     o b10-resolver -- Recursive name server. This process handles incoming
+       queries.
+     o b10-stats -- Statistics collection daemon. This process collects and
+       reports statistics data.
+     o b10-xfrin -- Incoming zone transfer service. This process is used to
+       transfer a new copy of a zone into BIND 10, when acting as a secondary
+       server.
+     o b10-xfrout -- Outgoing zone transfer service. This process is used to
+       handle transfer requests to send a local zone to a remote secondary
+       server, when acting as a master server.
+     o b10-zonemgr -- Secondary manager. This process keeps track of timers
+       and other necessary information for BIND 10 to act as a slave server.
+
+   These are ran automatically by bind10 and do not need to be run manually.
+
+Managing BIND 10
+
+   Once BIND 10 is running, a few commands are used to interact directly with
+   the system:
+
+     o bindctl -- interactive administration interface. This is a
+       command-line tool which allows an administrator to control BIND 10.
+     o b10-loadzone -- zone file loader. This tool will load standard
+       masterfile-format zone files into BIND 10.
+     o b10-cmdctl-usermgr -- user access control. This tool allows an
+       administrator to authorize additional users to manage BIND 10.
+
+   The tools and modules are covered in full detail in this guide. In
+   addition, manual pages are also provided in the default installation.
+
+   BIND 10 also provides libraries and programmer interfaces for C++ and
+   Python for the message bus, configuration backend, and, of course, DNS.
+   These include detailed developer documentation and code examples.
+
+Chapter 2. Installation
+
+   Table of Contents
+
+   Building Requirements
+
+   Quick start
+
+   Installation from source
+
+                Download Tar File
+
+                Retrieve from Git
+
+                Configure before the build
+
+                Build
+
+                Install
+
+                Install Hierarchy
+
+Building Requirements
+
+   In addition to the run-time requirements, building BIND 10 from source
+   code requires various development include headers.
+
+  Note
+
+   Some operating systems have split their distribution packages into a
+   run-time and a development package. You will need to install the
+   development package versions, which include header files and libraries, to
+   build BIND 10 from source code.
+
+   Building from source code requires the Boost build-time headers. At least
+   Boost version 1.35 is required.
+
+   To build BIND 10, also install the Botan (at least version 1.8) and the
+   log4cplus (at least version 1.0.3) development include headers.
+
+   The Python Library and Python _sqlite3 module are required to enable the
+   Xfrout and Xfrin support.
+
+  Note
+
+   The Python related libraries and modules need to be built for Python 3.1.
+
+   Building BIND 10 also requires a C++ compiler and standard development
+   headers, make, and pkg-config. BIND 10 builds have been tested with GCC
+   g++ 3.4.3, 4.1.2, 4.1.3, 4.2.1, 4.3.2, and 4.4.1; Clang++ 2.8; and Sun C++
+   5.10.
+
+Quick start
+
+  Note
+
+   This quickly covers the standard steps for installing and deploying BIND
+   10 as an authoritative name server using its defaults. For
+   troubleshooting, full customizations and further details, see the
+   respective chapters in the BIND 10 guide.
+
+   To quickly get started with BIND 10, follow these steps.
+
+    1. Install required build dependencies.
+    2. Download the BIND 10 source tar file from
+       ftp://ftp.isc.org/isc/bind10/.
+    3. Extract the tar file:
+
+ $ gzcat bind10-VERSION.tar.gz | tar -xvf -
+
+    4. Go into the source and run configure:
+
+ $ cd bind10-VERSION
+   $ ./configure
+
+    5. Build it:
+
+ $ make
+
+    6. Install it (to default /usr/local):
+
+ $ make install
+
+    7. Start the server:
+
+ $ /usr/local/sbin/bind10
+
+    8. Test it; for example:
+
+ $ dig @127.0.0.1 -c CH -t TXT authors.bind
+
+    9. Load desired zone file(s), for example:
+
+ $ b10-loadzone your.zone.example.org
+
+   10. Test the new zone.
+
+Installation from source
+
+   BIND 10 is open source software written in C++ and Python. It is freely
+   available in source code form from ISC via the Git code revision control
+   system or as a downloadable tar file. It may also be available in
+   pre-compiled ready-to-use packages from operating system vendors.
+
+  Download Tar File
+
+   Downloading a release tar file is the recommended method to obtain the
+   source code.
+
+   The BIND 10 releases are available as tar file downloads from
+   ftp://ftp.isc.org/isc/bind10/. Periodic development snapshots may also be
+   available.
+
+  Retrieve from Git
+
+   Downloading this "bleeding edge" code is recommended only for developers
+   or advanced users. Using development code in a production environment is
+   not recommended.
+
+  Note
+
+   When using source code retrieved via Git additional software will be
+   required: automake (v1.11 or newer), libtoolize, and autoconf (2.59 or
+   newer). These may need to be installed.
+
+   The latest development code, including temporary experiments and
+   un-reviewed code, is available via the BIND 10 code revision control
+   system. This is powered by Git and all the BIND 10 development is public.
+   The leading development is done in the "master".
+
+   The code can be checked out from git://bind10.isc.org/bind10; for example:
+
+ $ git clone git://bind10.isc.org/bind10
+
+   When checking out the code from the code version control system, it
+   doesn't include the generated configure script, Makefile.in files, nor the
+   related configure files. They can be created by running autoreconf with
+   the --install switch. This will run autoconf, aclocal, libtoolize,
+   autoheader, automake, and related commands.
+
+  Configure before the build
+
+   BIND 10 uses the GNU Build System to discover build environment details.
+   To generate the makefiles using the defaults, simply run:
+
+ $ ./configure
+
+   Run ./configure with the --help switch to view the different options. The
+   commonly-used options are:
+
+   --prefix
+           Define the installation location (the default is /usr/local/).
+
+   --with-boost-include
+           Define the path to find the Boost headers.
+
+   --with-pythonpath
+           Define the path to Python 3.1 if it is not in the standard
+           execution path.
+
+   --with-gtest
+           Enable building the C++ Unit Tests using the Google Tests
+           framework. Optionally this can define the path to the gtest header
+           files and library.
+
+   For example, the following configures it to find the Boost headers, find
+   the Python interpreter, and sets the installation location:
+
+ $ ./configure \
+       --with-boost-include=/usr/pkg/include \
+       --with-pythonpath=/usr/pkg/bin/python3.1 \
+       --prefix=/opt/bind10
+
+   If the configure fails, it may be due to missing or old dependencies.
+
+  Build
+
+   After the configure step is complete, to build the executables from the
+   C++ code and prepare the Python scripts, run:
+
+ $ make
+
+  Install
+
+   To install the BIND 10 executables, support files, and documentation, run:
+
+ $ make install
+
+  Note
+
+   The install step may require superuser privileges.
+
+  Install Hierarchy
+
+   The following is the layout of the complete BIND 10 installation:
+
+     o bin/ -- general tools and diagnostic clients.
+     o etc/bind10-devel/ -- configuration files.
+     o lib/ -- libraries and python modules.
+     o libexec/bind10-devel/ -- executables that a user wouldn't normally run
+       directly and are not run independently. These are the BIND 10 modules
+       which are daemons started by the bind10 tool.
+     o sbin/ -- commands used by the system administrator.
+     o share/bind10-devel/ -- configuration specifications.
+     o share/man/ -- manual pages (online documentation).
+     o var/bind10-devel/ -- data source and configuration databases.
+
+Chapter 3. Starting BIND10 with bind10
+
+   Table of Contents
+
+   Starting BIND 10
+
+   BIND 10 provides the bind10 command which starts up the required
+   processes. bind10 will also restart processes that exit unexpectedly. This
+   is the only command needed to start the BIND 10 system.
+
+   After starting the b10-msgq communications channel, bind10 connects to it,
+   runs the configuration manager, and reads its own configuration. Then it
+   starts the other modules.
+
+   The b10-msgq and b10-cfgmgr services make up the core. The b10-msgq daemon
+   provides the communication channel between every part of the system. The
+   b10-cfgmgr daemon is always needed by every module, if only to send
+   information about themselves somewhere, but more importantly to ask about
+   their own settings, and about other modules. The bind10 master process
+   will also start up b10-cmdctl for admins to communicate with the system,
+   b10-auth for authoritative DNS service or b10-resolver for recursive name
+   service, b10-stats for statistics collection, b10-xfrin for inbound DNS
+   zone transfers, b10-xfrout for outbound DNS zone transfers, and
+   b10-zonemgr for secondary service.
+
+Starting BIND 10
+
+   To start the BIND 10 service, simply run bind10. Run it with the --verbose
+   switch to get additional debugging or diagnostic output.
+
+  Note
+
+   If the setproctitle Python module is detected at start up, the process
+   names for the Python-based daemons will be renamed to better identify them
+   instead of just "python". This is not needed on some operating systems.
+
+Chapter 4. Command channel
+
+   The BIND 10 components use the b10-msgq message routing daemon to
+   communicate with other BIND 10 components. The b10-msgq implements what is
+   called the "Command Channel". Processes intercommunicate by sending
+   messages on the command channel. Example messages include shutdown, get
+   configurations, and set configurations. This Command Channel is not used
+   for DNS message passing. It is used only to control and monitor the BIND
+   10 system.
+
+   Administrators do not communicate directly with the b10-msgq daemon. By
+   default, BIND 10 uses port 9912 for the b10-msgq service. It listens on
+   127.0.0.1.
+
+Chapter 5. Configuration manager
+
+   The configuration manager, b10-cfgmgr, handles all BIND 10 system
+   configuration. It provides persistent storage for configuration, and
+   notifies running modules of configuration changes.
+
+   The b10-auth and b10-xfrin daemons and other components receive their
+   configurations from the configuration manager over the b10-msgq command
+   channel.
+
+   The administrator doesn't connect to it directly, but uses a user
+   interface to communicate with the configuration manager via b10-cmdctl's
+   REST-ful interface. b10-cmdctl is covered in Chapter 6, Remote control
+   daemon.
+
+  Note
+
+   The development prototype release only provides the bindctl as a user
+   interface to b10-cmdctl. Upcoming releases will provide another
+   interactive command-line interface and a web-based interface.
+
+   The b10-cfgmgr daemon can send all specifications and all current settings
+   to the bindctl client (via b10-cmdctl).
+
+   b10-cfgmgr relays configurations received from b10-cmdctl to the
+   appropriate modules.
+
+   The stored configuration file is at
+   /usr/local/var/bind10-devel/b10-config.db. (The full path is what was
+   defined at build configure time for --localstatedir. The default is
+   /usr/local/var/.) The format is loosely based on JSON and is directly
+   parseable python, but this may change in a future version. This
+   configuration data file is not manually edited by the administrator.
+
+   The configuration manager does not have any command line arguments.
+   Normally it is not started manually, but is automatically started using
+   the bind10 master process (as covered in Chapter 3, Starting BIND10 with
+   bind10).
+
+Chapter 6. Remote control daemon
+
+   Table of Contents
+
+   Configuration specification for b10-cmdctl
+
+   b10-cmdctl is the gateway between administrators and the BIND 10 system.
+   It is a HTTPS server that uses standard HTTP Digest Authentication for
+   username and password validation. It provides a REST-ful interface for
+   accessing and controlling BIND 10.
+
+   When b10-cmdctl starts, it firsts asks b10-cfgmgr about what modules are
+   running and what their configuration is (over the b10-msgq channel). Then
+   it will start listening on HTTPS for clients -- the user interface -- such
+   as bindctl.
+
+   b10-cmdctl directly sends commands (received from the user interface) to
+   the specified component. Configuration changes are actually commands to
+   b10-cfgmgr so are sent there.
+
+   The HTTPS server requires a private key, such as a RSA PRIVATE KEY. The
+   default location is at /usr/local/etc/bind10-devel/cmdctl-keyfile.pem. (A
+   sample key is at /usr/local/share/bind10-devel/cmdctl-keyfile.pem.) It
+   also uses a certificate located at
+   /usr/local/etc/bind10-devel/cmdctl-certfile.pem. (A sample certificate is
+   at /usr/local/share/bind10-devel/cmdctl-certfile.pem.) This may be a
+   self-signed certificate or purchased from a certification authority.
+
+  Note
+
+   The HTTPS server doesn't support a certificate request from a client (at
+   this time). The b10-cmdctl daemon does not provide a public service. If
+   any client wants to control BIND 10, then a certificate needs to be first
+   received from the BIND 10 administrator. The BIND 10 installation provides
+   a sample PEM bundle that matches the sample key and certificate.
+
+   The b10-cmdctl daemon also requires the user account file located at
+   /usr/local/etc/bind10-devel/cmdctl-accounts.csv. This comma-delimited file
+   lists the accounts with a user name, hashed password, and salt. (A sample
+   file is at /usr/local/share/bind10-devel/cmdctl-accounts.csv. It contains
+   the user named "root" with the password "bind10".)
+
+   The administrator may create a user account with the b10-cmdctl-usermgr
+   tool.
+
+   By default the HTTPS server listens on the localhost port 8080. The port
+   can be set by using the --port command line option. The address to listen
+   on can be set using the --address command line argument. Each HTTPS
+   connection is stateless and timesout in 1200 seconds by default. This can
+   be redefined by using the --idle-timeout command line argument.
+
+Configuration specification for b10-cmdctl
+
+   The configuration items for b10-cmdctl are: key_file cert_file
+   accounts_file
+
+   The control commands are: print_settings shutdown
+
+Chapter 7. Control and configure user interface
+
+  Note
+
+   For this development prototype release, bindctl is the only user
+   interface. It is expected that upcoming releases will provide another
+   interactive command-line interface and a web-based interface for
+   controlling and configuring BIND 10.
+
+   The bindctl tool provides an interactive prompt for configuring,
+   controlling, and querying the BIND 10 components. It communicates directly
+   with a REST-ful interface over HTTPS provided by b10-cmdctl. It doesn't
+   communicate to any other components directly.
+
+   Configuration changes are actually commands to b10-cfgmgr. So when bindctl
+   sends a configuration, it is sent to b10-cmdctl (over a HTTPS connection);
+   then b10-cmdctl sends the command (over a b10-msgq command channel) to
+   b10-cfgmgr which then stores the details and relays (over a b10-msgq
+   command channel) the configuration on to the specified module.
+
+Chapter 8. Authoritative Server
+
+   Table of Contents
+
+   Server Configurations
+
+   Data Source Backends
+
+   Loading Master Zones Files
+
+   The b10-auth is the authoritative DNS server. It supports EDNS0 and
+   DNSSEC. It supports IPv6. Normally it is started by the bind10 master
+   process.
+
+Server Configurations
+
+   b10-auth is configured via the b10-cfgmgr configuration manager. The
+   module name is "Auth". The configuration data item is:
+
+   database_file
+           This is an optional string to define the path to find the SQLite3
+           database file. Note: Later the DNS server will use various data
+           source backends. This may be a temporary setting until then.
+
+   The configuration command is:
+
+   shutdown
+           Stop the authoritative DNS server.
+
+Data Source Backends
+
+  Note
+
+   For the development prototype release, b10-auth supports a SQLite3 data
+   source backend and in-memory data source backend. Upcoming versions will
+   be able to use multiple different data sources, such as MySQL and Berkeley
+   DB.
+
+   By default, the SQLite3 backend uses the data file located at
+   /usr/local/var/bind10-devel/zone.sqlite3. (The full path is what was
+   defined at build configure time for --localstatedir. The default is
+   /usr/local/var/.) This data file location may be changed by defining the
+   "database_file" configuration.
+
+Loading Master Zones Files
+
+   RFC 1035 style DNS master zone files may imported into a BIND 10 data
+   source by using the b10-loadzone utility.
+
+   b10-loadzone supports the following special directives (control entries):
+
+   $INCLUDE
+           Loads an additional zone file. This may be recursive.
+
+   $ORIGIN
+           Defines the relative domain name.
+
+   $TTL
+           Defines the time-to-live value used for following records that
+           don't include a TTL.
+
+   The -o argument may be used to define the default origin for loaded zone
+   file records.
+
+  Note
+
+   In the development prototype release, only the SQLite3 back end is used.
+   By default, it stores the zone data in
+   /usr/local/var/bind10-devel/zone.sqlite3 unless the -d switch is used to
+   set the database filename. Multiple zones are stored in a single SQLite3
+   zone database.
+
+   If you reload a zone already existing in the database, all records from
+   that prior zone disappear and a whole new set appears.
+
+Chapter 9. Incoming Zone Transfers
+
+   Table of Contents
+
+   Configuration for Incoming Zone Transfers
+
+   Enabling IXFR
+
+   Trigger an Incoming Zone Transfer Manually
+
+   Incoming zones are transferred using the b10-xfrin process which is
+   started by bind10. When received, the zone is stored in the corresponding
+   BIND 10 data source, and its records can be served by b10-auth. In
+   combination with b10-zonemgr (for automated SOA checks), this allows the
+   BIND 10 server to provide "secondary" service.
+
+   The b10-xfrin process supports both AXFR and IXFR. Due to some
+   implementation limitations of the current development release, however, it
+   only tries AXFR by default, and care should be taken to enable IXFR.
+
+  Note
+
+   In the current development release of BIND 10, incoming zone transfers are
+   only available for SQLite3-based data sources, that is, they don't work
+   for an in-memory data source.
+
+Configuration for Incoming Zone Transfers
+
+   In practice, you need to specify a list of secondary zones to enable
+   incoming zone transfers for these zones (you can still trigger a zone
+   transfer manually, without a prior configuration (see below)).
+
+   For example, to enable zone transfers for a zone named "example.com"
+   (whose master address is assumed to be 2001:db8::53 here), run the
+   following at the bindctl prompt:
+
+ > config add Xfrin/zones
+ > config set Xfrin/zones[0]/name "example.com"
+ > config set Xfrin/zones[0]/master_addr "2001:db8::53"
+ > config commit
+
+   (We assume there has been no zone configuration before).
+
+Enabling IXFR
+
+   As noted above, b10-xfrin uses AXFR for zone transfers by default. To
+   enable IXFR for zone transfers for a particular zone, set the use_ixfr
+   configuration parameter to true. In the above example of configuration
+   sequence, you'll need to add the following before performing commit:
+
+ > config set Xfrin/zones[0]/use_ixfr true
+
+  Note
+
+   One reason why IXFR is disabled by default in the current release is
+   because it does not support automatic fallback from IXFR to AXFR when it
+   encounters a primary server that doesn't support outbound IXFR (and, not
+   many existing implementations support it). Another, related reason is that
+   it does not use AXFR even if it has no knowledge about the zone (like at
+   the very first time the secondary server is set up). IXFR requires the
+   "current version" of the zone, so obviously it doesn't work in this
+   situation and AXFR is the only workable choice. The current release of
+   b10-xfrin does not make this selection automatically. These features will
+   be implemented in a near future version, at which point we will enable
+   IXFR by default.
+
+Trigger an Incoming Zone Transfer Manually
+
+   To manually trigger a zone transfer to retrieve a remote zone, you may use
+   the bindctl utility. For example, at the bindctl prompt run:
+
+ > Xfrin retransfer zone_name="foo.example.org" master=192.0.2.99
+
+Chapter 10. Outbound Zone Transfers
+
+   The b10-xfrout process is started by bind10. When the b10-auth
+   authoritative DNS server receives an AXFR request, b10-xfrout sends the
+   zone. This is used to provide master DNS service to share zones to
+   secondary name servers. The b10-xfrout is also used to send NOTIFY
+   messages to slaves.
+
+  Note
+
+   The current development release of BIND 10 only supports AXFR. (IXFR is
+   not supported.) Access control is not yet provided.
+
+Chapter 11. Secondary Manager
+
+   The b10-zonemgr process is started by bind10. It keeps track of SOA
+   refresh, retry, and expire timers and other details for BIND 10 to perform
+   as a slave. When the b10-auth authoritative DNS server receives a NOTIFY
+   message, b10-zonemgr may tell b10-xfrin to do a refresh to start an
+   inbound zone transfer. The secondary manager resets its counters when a
+   new zone is transferred in.
+
+  Note
+
+   Access control (such as allowing notifies) is not yet provided. The
+   primary/secondary service is not yet complete.
+
+Chapter 12. Recursive Name Server
+
+   Table of Contents
+
+   Access Control
+
+   Forwarding
+
+   The b10-resolver process is started by bind10.
+
+   The main bind10 process can be configured to select to run either the
+   authoritative or resolver or both. By default, it starts the authoritative
+   service. You may change this using bindctl, for example:
+
+ > config set Boss/start_auth false
+ > config set Boss/start_resolver true
+ > config commit
+
+   The master bind10 will stop and start the desired services.
+
+   By default, the resolver listens on port 53 for 127.0.0.1 and ::1. The
+   following example shows how it can be configured to listen on an
+   additional address (and port):
+
+ > config add Resolver/listen_on
+ > config set Resolver/listen_on[2]/address "192.168.1.1"
+ > config set Resolver/listen_on[2]/port 53
+ > config commit
+
+   (Replace the "2" as needed; run "config show Resolver/listen_on" if
+   needed.)
+
+Access Control
+
+   By default, the b10-resolver daemon only accepts DNS queries from the
+   localhost (127.0.0.1 and ::1). The Resolver/query_acl configuration may be
+   used to reject, drop, or allow specific IPs or networks. This
+   configuration list is first match.
+
+   The configuration's action item may be set to "ACCEPT" to allow the
+   incoming query, "REJECT" to respond with a DNS REFUSED return code, or
+   "DROP" to ignore the query without any response (such as a blackhole). For
+   more information, see the respective debugging messages:
+   RESOLVER_QUERY_ACCEPTED, RESOLVER_QUERY_REJECTED, and
+   RESOLVER_QUERY_DROPPED.
+
+   The required configuration's from item is set to an IPv4 or IPv6 address,
+   addresses with an network mask, or to the special lowercase keywords
+   "any6" (for any IPv6 address) or "any4" (for any IPv4 address).
+
+   For example to allow the 192.168.1.0/24 network to use your recursive name
+   server, at the bindctl prompt run:
+
+ > config add Resolver/query_acl
+ > config set Resolver/query_acl[2]/action "ACCEPT"
+ > config set Resolver/query_acl[2]/from "192.168.1.0/24"
+ > config commit
+
+   (Replace the "2" as needed; run "config show Resolver/query_acl" if
+   needed.)
+
+  Note
+
+   This prototype access control configuration syntax may be changed.
+
+Forwarding
+
+   To enable forwarding, the upstream address and port must be configured to
+   forward queries to, such as:
+
+ > config set Resolver/forward_addresses [{ "address": "192.168.1.1", "port": 53 }]
+ > config commit
+
+   (Replace 192.168.1.1 to point to your full resolver.)
+
+   Normal iterative name service can be re-enabled by clearing the forwarding
+   address(es); for example:
+
+ > config set Resolver/forward_addresses []
+ > config commit
+
+Chapter 13. Statistics
+
+   The b10-stats process is started by bind10. It periodically collects
+   statistics data from various modules and aggregates it.
+
+   This stats daemon provides commands to identify if it is running, show
+   specified or all statistics data, show specified or all statistics data
+   schema, and set specified statistics data. For example, using bindctl:
+
+ > Stats show
+ {
+     "Auth": {
+         "queries.tcp": 1749,
+         "queries.udp": 867868
+     },
+     "Boss": {
+         "boot_time": "2011-01-20T16:59:03Z"
+     },
+     "Stats": {
+         "boot_time": "2011-01-20T16:59:05Z",
+         "last_update_time": "2011-01-20T17:04:05Z",
+         "lname": "4d3869d9_a at jreed.example.net",
+         "report_time": "2011-01-20T17:04:06Z",
+         "timestamp": 1295543046.823504
+     }
+ }
+
+
+Chapter 14. Logging
+
+   Table of Contents
+
+   Logging configuration
+
+                Loggers
+
+                Output Options
+
+                Example session
+
+   Logging Message Format
+
+Logging configuration
+
+   The logging system in BIND 10 is configured through the Logging module.
+   All BIND 10 modules will look at the configuration in Logging to see what
+   should be logged and to where.
+
+  Loggers
+
+   Within BIND 10, a message is logged through a component called a "logger".
+   Different parts of BIND 10 log messages through different loggers, and
+   each logger can be configured independently of one another.
+
+   In the Logging module, you can specify the configuration for zero or more
+   loggers; any that are not specified will take appropriate default values..
+
+   The three most important elements of a logger configuration are the name
+   (the component that is generating the messages), the severity (what to
+   log), and the output_options (where to log).
+
+    name (string)
+
+   Each logger in the system has a name, the name being that of the component
+   using it to log messages. For instance, if you want to configure logging
+   for the resolver module, you add an entry for a logger named "Resolver".
+   This configuration will then be used by the loggers in the Resolver
+   module, and all the libraries used by it.
+
+   If you want to specify logging for one specific library within the module,
+   you set the name to module.library. For example, the logger used by the
+   nameserver address store component has the full name of "Resolver.nsas".
+   If there is no entry in Logging for a particular library, it will use the
+   configuration given for the module.
+
+   To illustrate this, suppose you want the cache library to log messages of
+   severity DEBUG, and the rest of the resolver code to log messages of
+   severity INFO. To achieve this you specify two loggers, one with the name
+   "Resolver" and severity INFO, and one with the name "Resolver.cache" with
+   severity DEBUG. As there are no entries for other libraries (e.g. the
+   nsas), they will use the configuration for the module ("Resolver"), so
+   giving the desired behavior.
+
+   One special case is that of a module name of "*" (asterisks), which is
+   interpreted as any module. You can set global logging options by using
+   this, including setting the logging configuration for a library that is
+   used by multiple modules (e.g. "*.config" specifies the configuration
+   library code in whatever module is using it).
+
+   If there are multiple logger specifications in the configuration that
+   might match a particular logger, the specification with the more specific
+   logger name takes precedence. For example, if there are entries for for
+   both "*" and "Resolver", the resolver module -- and all libraries it uses
+   -- will log messages according to the configuration in the second entry
+   ("Resolver"). All other modules will use the configuration of the first
+   entry ("*"). If there was also a configuration entry for "Resolver.cache",
+   the cache library within the resolver would use that in preference to the
+   entry for "Resolver".
+
+   One final note about the naming. When specifying the module name within a
+   logger, use the name of the module as specified in bindctl, e.g.
+   "Resolver" for the resolver module, "Xfrout" for the xfrout module, etc.
+   When the message is logged, the message will include the name of the
+   logger generating the message, but with the module name replaced by the
+   name of the process implementing the module (so for example, a message
+   generated by the "Auth.cache" logger will appear in the output with a
+   logger name of "b10-auth.cache").
+
+    severity (string)
+
+   This specifies the category of messages logged. Each message is logged
+   with an associated severity which may be one of the following (in
+   descending order of severity):
+
+     o FATAL
+     o ERROR
+     o WARN
+     o INFO
+     o DEBUG
+
+   When the severity of a logger is set to one of these values, it will only
+   log messages of that severity, and the severities above it. The severity
+   may also be set to NONE, in which case all messages from that logger are
+   inhibited.
+
+    output_options (list)
+
+   Each logger can have zero or more output_options. These specify where log
+   messages are sent to. These are explained in detail below.
+
+   The other options for a logger are:
+
+    debuglevel (integer)
+
+   When a logger's severity is set to DEBUG, this value specifies what debug
+   messages should be printed. It ranges from 0 (least verbose) to 99 (most
+   verbose).
+
+   If severity for the logger is not DEBUG, this value is ignored.
+
+    additive (true or false)
+
+   If this is true, the output_options from the parent will be used. For
+   example, if there are two loggers configured; "Resolver" and
+   "Resolver.cache", and additive is true in the second, it will write the
+   log messages not only to the destinations specified for "Resolver.cache",
+   but also to the destinations as specified in the output_options in the
+   logger named "Resolver".
+
+  Output Options
+
+   The main settings for an output option are the destination and a value
+   called output, the meaning of which depends on the destination that is
+   set.
+
+    destination (string)
+
+   The destination is the type of output. It can be one of:
+
+     o console
+     o file
+     o syslog
+
+    output (string)
+
+   Depending on what is set as the output destination, this value is
+   interpreted as follows:
+
+   destination is "console"
+           The value of output must be one of "stdout" (messages printed to
+           standard output) or "stderr" (messages printed to standard error).
+
+   destination is "file"
+           The value of output is interpreted as a file name; log messages
+           will be appended to this file.
+
+   destination is "syslog"
+           The value of output is interpreted as the syslog facility (e.g.
+           local0) that should be used for log messages.
+
+   The other options for output_options are:
+
+      flush (true of false)
+
+   Flush buffers after each log message. Doing this will reduce performance
+   but will ensure that if the program terminates abnormally, all messages up
+   to the point of termination are output.
+
+      maxsize (integer)
+
+   Only relevant when destination is file, this is maximum file size of
+   output files in bytes. When the maximum size is reached, the file is
+   renamed and a new file opened. (For example, a ".1" is appended to the
+   name -- if a ".1" file exists, it is renamed ".2", etc.)
+
+   If this is 0, no maximum file size is used.
+
+      maxver (integer)
+
+   Maximum number of old log files to keep around when rolling the output
+   file. Only relevant when destination is "file".
+
+  Example session
+
+   In this example we want to set the global logging to write to the file
+   /var/log/my_bind10.log, at severity WARN. We want the authoritative server
+   to log at DEBUG with debuglevel 40, to a different file
+   (/tmp/debug_messages).
+
+   Start bindctl.
+
+ ["login success "]
+ > config show Logging
+ Logging/loggers []      list
+
+   By default, no specific loggers are configured, in which case the severity
+   defaults to INFO and the output is written to stderr.
+
+   Let's first add a default logger:
+
+ > config add Logging/loggers
+ > config show Logging
+ Logging/loggers/        list    (modified)
+
+   The loggers value line changed to indicate that it is no longer an empty
+   list:
+
+ > config show Logging/loggers
+ Logging/loggers[0]/name ""      string  (default)
+ Logging/loggers[0]/severity     "INFO"  string  (default)
+ Logging/loggers[0]/debuglevel   0       integer (default)
+ Logging/loggers[0]/additive     false   boolean (default)
+ Logging/loggers[0]/output_options       []      list    (default)
+
+   The name is mandatory, so we must set it. We will also change the severity
+   as well. Let's start with the global logger.
+
+ > config set Logging/loggers[0]/name *
+ > config set Logging/loggers[0]/severity WARN
+ > config show Logging/loggers
+ Logging/loggers[0]/name "*"     string  (modified)
+ Logging/loggers[0]/severity     "WARN"  string  (modified)
+ Logging/loggers[0]/debuglevel   0       integer (default)
+ Logging/loggers[0]/additive     false   boolean (default)
+ Logging/loggers[0]/output_options       []      list    (default)
+
+   Of course, we need to specify where we want the log messages to go, so we
+   add an entry for an output option.
+
+ >  config add Logging/loggers[0]/output_options
+ >  config show Logging/loggers[0]/output_options
+ Logging/loggers[0]/output_options[0]/destination        "console"       string  (default)
+ Logging/loggers[0]/output_options[0]/output     "stdout"        string  (default)
+ Logging/loggers[0]/output_options[0]/flush      false   boolean (default)
+ Logging/loggers[0]/output_options[0]/maxsize    0       integer (default)
+ Logging/loggers[0]/output_options[0]/maxver     0       integer (default)
+
+   These aren't the values we are looking for.
+
+ >  config set Logging/loggers[0]/output_options[0]/destination file
+ >  config set Logging/loggers[0]/output_options[0]/output /var/log/bind10.log
+ >  config set Logging/loggers[0]/output_options[0]/maxsize 30000
+ >  config set Logging/loggers[0]/output_options[0]/maxver 8
+
+   Which would make the entire configuration for this logger look like:
+
+ >  config show all Logging/loggers
+ Logging/loggers[0]/name "*"     string  (modified)
+ Logging/loggers[0]/severity     "WARN"  string  (modified)
+ Logging/loggers[0]/debuglevel   0       integer (default)
+ Logging/loggers[0]/additive     false   boolean (default)
+ Logging/loggers[0]/output_options[0]/destination        "file"  string  (modified)
+ Logging/loggers[0]/output_options[0]/output     "/var/log/bind10.log"   string  (modified)
+ Logging/loggers[0]/output_options[0]/flush      false   boolean (default)
+ Logging/loggers[0]/output_options[0]/maxsize    30000   integer (modified)
+ Logging/loggers[0]/output_options[0]/maxver     8       integer (modified)
+
+   That looks OK, so let's commit it before we add the configuration for the
+   authoritative server's logger.
+
+ >  config commit
+
+   Now that we have set it, and checked each value along the way, adding a
+   second entry is quite similar.
+
+ >  config add Logging/loggers
+ >  config set Logging/loggers[1]/name Auth
+ >  config set Logging/loggers[1]/severity DEBUG
+ >  config set Logging/loggers[1]/debuglevel 40
+ >  config add Logging/loggers[1]/output_options
+ >  config set Logging/loggers[1]/output_options[0]/destination file
+ >  config set Logging/loggers[1]/output_options[0]/output /tmp/auth_debug.log
+ >  config commit
+
+   And that's it. Once we have found whatever it was we needed the debug
+   messages for, we can simply remove the second logger to let the
+   authoritative server use the same settings as the rest.
+
+ >  config remove Logging/loggers[1]
+ >  config commit
+
+   And every module will now be using the values from the logger named "*".
+
+Logging Message Format
+
+   Each message written by BIND 10 to the configured logging destinations
+   comprises a number of components that identify the origin of the message
+   and, if the message indicates a problem, information about the problem
+   that may be useful in fixing it.
+
+   Consider the message below logged to a file:
+
+ 2011-06-15 13:48:22.034 ERROR [b10-resolver.asiolink]
+     ASIODNS_OPENSOCK error 111 opening TCP socket to 127.0.0.1(53)
+
+   Note: the layout of messages written to the system logging file (syslog)
+   may be slightly different. This message has been split across two lines
+   here for display reasons; in the logging file, it will appear on one
+   line.)
+
+   The log message comprises a number of components:
+
+   2011-06-15 13:48:22.034
+
+           The date and time at which the message was generated.
+
+   ERROR
+
+           The severity of the message.
+
+   [b10-resolver.asiolink]
+
+           The source of the message. This comprises two components: the BIND
+           10 process generating the message (in this case, b10-resolver) and
+           the module within the program from which the message originated
+           (which in the example is the asynchronous I/O link module,
+           asiolink).
+
+   ASIODNS_OPENSOCK
+
+           The message identification. Every message in BIND 10 has a unique
+           identification, which can be used as an index into the BIND 10
+           Messages Manual (http://bind10.isc.org/docs/bind10-messages.html)
+           from which more information can be obtained.
+
+   error 111 opening TCP socket to 127.0.0.1(53)
+
+           A brief description of the cause of the problem. Within this text,
+           information relating to the condition that caused the message to
+           be logged will be included. In this example, error number 111 (an
+           operating system-specific error number) was encountered when
+           trying to open a TCP connection to port 53 on the local system
+           (address 127.0.0.1). The next step would be to find out the reason
+           for the failure by consulting your system's documentation to
+           identify what error number 111 means.
diff --git a/doc/guide/bind10-guide.xml b/doc/guide/bind10-guide.xml
index 34607e9..21bb671 100644
--- a/doc/guide/bind10-guide.xml
+++ b/doc/guide/bind10-guide.xml
@@ -41,9 +41,10 @@
       </para>
       <para>
         This is the reference guide for BIND 10 version &__VERSION__;.
-	The most up-to-date version of this document, along with
-	other documents for BIND 10, can be found at <ulink
-	url="http://bind10.isc.org/docs"/>.  </para> </abstract>
+	The most up-to-date version of this document (in PDF, HTML,
+	and plain text formats), along with other documents for
+	BIND 10, can be found at <ulink url="http://bind10.isc.org/docs"/>.
+	</para> </abstract>
 
       <releaseinfo>This is the reference guide for BIND 10 version
         &__VERSION__;.</releaseinfo>
@@ -1271,6 +1272,7 @@ TODO
       development release, however, it only tries AXFR by default,
       and care should be taken to enable IXFR.
     </para>
+<!-- TODO: http://bind10.isc.org/ticket/1279 -->
 
     <note><simpara>
      In the current development release of BIND 10, incoming zone
@@ -1278,13 +1280,19 @@ TODO
      that is, they don't work for an in-memory data source.
     </simpara></note>
 
-    <para>
-      To enable IXFR, you need to
-      configure <command>b10-xfrin</command> with an explicit zone
-      configuration for the zone.
-      For example, to enable IXFR for a zone named "example.com"
-      (whose master address is assumed to be 2001:db8::53 here),
-      run the following at the <command>bindctl</command> prompt:
+    <section>
+      <title>Configuration for Incoming Zone Transfers</title>
+      <para>
+	In practice, you need to specify a list of secondary zones to
+	enable incoming zone transfers for these zones (you can still
+	trigger a zone transfer manually, without a prior configuration
+	(see below)).
+      </para>
+
+      <para>
+	For example, to enable zone transfers for a zone named "example.com"
+	(whose master address is assumed to be 2001:db8::53 here),
+	run the following at the <command>bindctl</command> prompt:
 
       <screen>> <userinput>config add Xfrin/zones</userinput>
 > <userinput>config set Xfrin/zones[0]/name "<option>example.com</option>"</userinput>
@@ -1292,16 +1300,23 @@ TODO
 > <userinput>config commit</userinput></screen>
 
       (We assume there has been no zone configuration before).
-      Note that you do NOT have to explicitly enable IXFR in the zone
-      configuration; once it's defined, IXFR is enabled by default.
-      This also means if you specify a zone configuration for some
-      other reason but don't want to use IXFR for that zone, you need
-      to disable it explicitly:
+      </para>
+    </section>
 
-      <screen>> <userinput>config set Xfrin/zones[0]/ixfr_disabled true</userinput></screen>
-    </para>
+    <section>
+      <title>Enabling IXFR</title>
+      <para>
+        As noted above, <command>b10-xfrin</command> uses AXFR for
+        zone transfers by default.  To enable IXFR for zone transfers
+        for a particular zone, set the <userinput>use_ixfr</userinput>
+        configuration parameter to <userinput>true</userinput>.
+        In the above example of configuration sequence, you'll need
+        to add the following before performing <userinput>commit</userinput>:
+      <screen>> <userinput>config set Xfrin/zones[0]/use_ixfr true</userinput></screen>
+      </para>
 
-    <para>
+<!-- TODO: http://bind10.isc.org/ticket/1279 -->
+      <note><simpara>
       One reason why IXFR is disabled by default in the current
       release is because it does not support automatic fallback from IXFR to
       AXFR when it encounters a primary server that doesn't support
@@ -1315,7 +1330,8 @@ TODO
       make this selection automatically.
       These features will be implemented in a near future
       version, at which point we will enable IXFR by default.
-    </para>
+      </simpara></note>
+    </section>
 
 <!-- TODO:
 
@@ -1328,13 +1344,18 @@ what if a NOTIFY is sent?
 
 -->
 
-    <para>
-       To manually trigger a zone transfer to retrieve a remote zone,
-       you may use the <command>bindctl</command> utility.
-       For example, at the <command>bindctl</command> prompt run:
+    <section>
+      <title>Trigger an Incoming Zone Transfer Manually</title>
+
+      <para>
+	To manually trigger a zone transfer to retrieve a remote zone,
+	you may use the <command>bindctl</command> utility.
+	For example, at the <command>bindctl</command> prompt run:
+
+	<screen>> <userinput>Xfrin retransfer zone_name="<option>foo.example.org</option>" master=<option>192.0.2.99</option></userinput></screen>
+      </para>
+    </section>
 
-       <screen>> <userinput>Xfrin retransfer zone_name="<option>foo.example.org</option>" master=<option>192.0.2.99</option></userinput></screen>
-    </para>
 
 <!-- TODO: can that retransfer be used to identify a new zone? -->
 <!-- TODO: what if doesn't exist at that master IP? -->
diff --git a/doc/guide/bind10-messages.xml b/doc/guide/bind10-messages.xml
index f5c44b3..bade381 100644
--- a/doc/guide/bind10-messages.xml
+++ b/doc/guide/bind10-messages.xml
@@ -244,6 +244,14 @@ packet.
 </para></listitem>
 </varlistentry>
 
+<varlistentry id="AUTH_INVALID_STATISTICS_DATA">
+<term>AUTH_INVALID_STATISTICS_DATA invalid specification of statistics data specified</term>
+<listitem><para>
+An error was encountered when the authoritiative server specified
+statistics data which is invalid for the auth specification file.
+</para></listitem>
+</varlistentry>
+
 <varlistentry id="AUTH_LOAD_TSIG">
 <term>AUTH_LOAD_TSIG loading TSIG keys</term>
 <listitem><para>
@@ -581,6 +589,14 @@ started according to the configuration.
 </para></listitem>
 </varlistentry>
 
+<varlistentry id="BIND10_INVALID_STATISTICS_DATA">
+<term>BIND10_INVALID_STATISTICS_DATA invalid specification of statistics data specified</term>
+<listitem><para>
+An error was encountered when the boss module specified
+statistics data which is invalid for the boss specification file.
+</para></listitem>
+</varlistentry>
+
 <varlistentry id="BIND10_INVALID_USER">
 <term>BIND10_INVALID_USER invalid user: %1</term>
 <listitem><para>
@@ -1150,7 +1166,7 @@ Debug message. The resolver is trying to look up data in the RRset cache.
 </varlistentry>
 
 <varlistentry id="CACHE_RRSET_NOT_FOUND">
-<term>CACHE_RRSET_NOT_FOUND no RRset found for %1/%2/%3</term>
+<term>CACHE_RRSET_NOT_FOUND no RRset found for %1/%2/%3 in cache</term>
 <listitem><para>
 Debug message which can follow CACHE_RRSET_LOOKUP. This means the data is not
 in the cache.
@@ -1773,13 +1789,12 @@ means no limit.
 </para></listitem>
 </varlistentry>
 
-<varlistentry id="DATASRC_DATABASE_FIND_ERROR">
-<term>DATASRC_DATABASE_FIND_ERROR error retrieving data from datasource %1: %2</term>
+<varlistentry id="DATASRC_DATABASE_COVER_NSEC_UNSUPPORTED">
+<term>DATASRC_DATABASE_COVER_NSEC_UNSUPPORTED %1 doesn't support DNSSEC when asked for NSEC data covering %2</term>
 <listitem><para>
-This was an internal error while reading data from a datasource. This can either
-mean the specific data source implementation is not behaving correctly, or the
-data it provides is invalid. The current search is aborted.
-The error message contains specific information about the error.
+The datasource tried to provide an NSEC proof that the named domain does not
+exist, but the database backend doesn't support DNSSEC. No proof is included
+in the answer as a result.
 </para></listitem>
 </varlistentry>
 
@@ -1795,28 +1810,9 @@ name and type in the database.
 <term>DATASRC_DATABASE_FIND_TTL_MISMATCH TTL values differ in %1 for elements of %2/%3/%4, setting to %5</term>
 <listitem><para>
 The datasource backend provided resource records for the given RRset with
-different TTL values. The TTL of the RRSET is set to the lowest value, which
-is printed in the log message.
-</para></listitem>
-</varlistentry>
-
-<varlistentry id="DATASRC_DATABASE_FIND_UNCAUGHT_ERROR">
-<term>DATASRC_DATABASE_FIND_UNCAUGHT_ERROR uncaught general error retrieving data from datasource %1: %2</term>
-<listitem><para>
-There was an uncaught general exception while reading data from a datasource.
-This most likely points to a logic error in the code, and can be considered a
-bug. The current search is aborted. Specific information about the exception is
-printed in this error message.
-</para></listitem>
-</varlistentry>
-
-<varlistentry id="DATASRC_DATABASE_FIND_UNCAUGHT_ISC_ERROR">
-<term>DATASRC_DATABASE_FIND_UNCAUGHT_ISC_ERROR uncaught error retrieving data from datasource %1: %2</term>
-<listitem><para>
-There was an uncaught ISC exception while reading data from a datasource. This
-most likely points to a logic error in the code, and can be considered a bug.
-The current search is aborted. Specific information about the exception is
-printed in this error message.
+different TTL values. This isn't allowed on the wire and is considered
+an error, so we set it to the lowest value we found (but we don't modify the
+database). The data in database should be checked and fixed.
 </para></listitem>
 </varlistentry>
 
@@ -1846,6 +1842,15 @@ instead.
 </para></listitem>
 </varlistentry>
 
+<varlistentry id="DATASRC_DATABASE_FOUND_EMPTY_NONTERMINAL">
+<term>DATASRC_DATABASE_FOUND_EMPTY_NONTERMINAL empty non-terminal %2 in %1</term>
+<listitem><para>
+The domain name doesn't have any RRs, so it doesn't exist in the database.
+However, it has a subdomain, so it exists in the DNS address space. So we
+return NXRRSET instead of NXDOMAIN.
+</para></listitem>
+</varlistentry>
+
 <varlistentry id="DATASRC_DATABASE_FOUND_NXDOMAIN">
 <term>DATASRC_DATABASE_FOUND_NXDOMAIN search in datasource %1 resulted in NXDOMAIN for %2/%3/%4</term>
 <listitem><para>
@@ -1871,6 +1876,132 @@ returned is printed.
 </para></listitem>
 </varlistentry>
 
+<varlistentry id="DATASRC_DATABASE_ITERATE">
+<term>DATASRC_DATABASE_ITERATE iterating zone %1</term>
+<listitem><para>
+The program is reading the whole zone, eg. not searching for data, but going
+through each of the RRsets there.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="DATASRC_DATABASE_ITERATE_END">
+<term>DATASRC_DATABASE_ITERATE_END iterating zone finished</term>
+<listitem><para>
+While iterating through the zone, the program reached end of the data.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="DATASRC_DATABASE_ITERATE_NEXT">
+<term>DATASRC_DATABASE_ITERATE_NEXT next RRset in zone is %1/%2</term>
+<listitem><para>
+While iterating through the zone, the program extracted next RRset from it.
+The name and RRtype of the RRset is indicated in the message.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="DATASRC_DATABASE_ITERATE_TTL_MISMATCH">
+<term>DATASRC_DATABASE_ITERATE_TTL_MISMATCH TTL values differ for RRs of %1/%2/%3, setting to %4</term>
+<listitem><para>
+While iterating through the zone, the time to live for RRs of the given RRset
+were found to be different. This isn't allowed on the wire and is considered
+an error, so we set it to the lowest value we found (but we don't modify the
+database). The data in database should be checked and fixed.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="DATASRC_DATABASE_UPDATER_COMMIT">
+<term>DATASRC_DATABASE_UPDATER_COMMIT updates committed for '%1/%2' on %3</term>
+<listitem><para>
+Debug information.  A set of updates to a zone has been successfully
+committed to the corresponding database backend.  The zone name,
+its class and the database name are printed.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="DATASRC_DATABASE_UPDATER_CREATED">
+<term>DATASRC_DATABASE_UPDATER_CREATED zone updater created for '%1/%2' on %3</term>
+<listitem><para>
+Debug information.  A zone updater object is created to make updates to
+the shown zone on the shown backend database.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="DATASRC_DATABASE_UPDATER_DESTROYED">
+<term>DATASRC_DATABASE_UPDATER_DESTROYED zone updater destroyed for '%1/%2' on %3</term>
+<listitem><para>
+Debug information.  A zone updater object is destroyed, either successfully
+or after failure of, making updates to the shown zone on the shown backend
+database.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="DATASRC_DATABASE_UPDATER_ROLLBACK">
+<term>DATASRC_DATABASE_UPDATER_ROLLBACK zone updates roll-backed for '%1/%2' on %3</term>
+<listitem><para>
+A zone updater is being destroyed without committing the changes.
+This would typically mean the update attempt was aborted due to some
+error, but may also be a bug of the application that forgets committing
+the changes.  The intermediate changes made through the updater won't
+be applied to the underlying database.  The zone name, its class, and
+the underlying database name are shown in the log message.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="DATASRC_DATABASE_UPDATER_ROLLBACKFAIL">
+<term>DATASRC_DATABASE_UPDATER_ROLLBACKFAIL failed to roll back zone updates for '%1/%2' on %3: %4</term>
+<listitem><para>
+A zone updater is being destroyed without committing the changes to
+the database, and attempts to rollback incomplete updates, but it
+unexpectedly fails.  The higher level implementation does not expect
+it to fail, so this means either a serious operational error in the
+underlying data source (such as a system failure of a database) or
+software bug in the underlying data source implementation.  In either
+case if this message is logged the administrator should carefully
+examine the underlying data source to see what exactly happens and
+whether the data is still valid.  The zone name, its class, and the
+underlying database name as well as the error message thrown from the
+database module are shown in the log message.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="DATASRC_DATABASE_WILDCARD">
+<term>DATASRC_DATABASE_WILDCARD constructing RRset %3 from wildcard %2 in %1</term>
+<listitem><para>
+The database doesn't contain directly matching domain, but it does contain a
+wildcard one which is being used to synthesize the answer.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="DATASRC_DATABASE_WILDCARD_CANCEL_NS">
+<term>DATASRC_DATABASE_WILDCARD_CANCEL_NS canceled wildcard match on %2 because %3 contains NS in %1</term>
+<listitem><para>
+The database was queried to provide glue data and it didn't find direct match.
+It could create it from given wildcard, but matching wildcards is forbidden
+under a zone cut, which was found. Therefore the delegation will be returned
+instead.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="DATASRC_DATABASE_WILDCARD_CANCEL_SUB">
+<term>DATASRC_DATABASE_WILDCARD_CANCEL_SUB wildcard %2 can't be used to construct %3 because %4 exists in %1</term>
+<listitem><para>
+The answer could be constructed using the wildcard, but the given subdomain
+exists, therefore this name is something like empty non-terminal (actually,
+from the protocol point of view, it is empty non-terminal, but the code
+discovers it differently).
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="DATASRC_DATABASE_WILDCARD_EMPTY">
+<term>DATASRC_DATABASE_WILDCARD_EMPTY implicit wildcard %2 used to construct %3 in %1</term>
+<listitem><para>
+The given wildcard exists implicitly in the domainspace, as empty nonterminal
+(eg. there's something like subdomain.*.example.org, so *.example.org exists
+implicitly, but is empty). This will produce NXRRSET, because the constructed
+domain is empty as well as the wildcard.
+</para></listitem>
+</varlistentry>
+
 <varlistentry id="DATASRC_DO_QUERY">
 <term>DATASRC_DO_QUERY handling query for '%1/%2'</term>
 <listitem><para>
@@ -2750,6 +2881,15 @@ generated.
 </para></listitem>
 </varlistentry>
 
+<varlistentry id="LIBXFRIN_DIFFERENT_TTL">
+<term>LIBXFRIN_DIFFERENT_TTL multiple data with different TTLs (%1, %2) on %3/%4. Adjusting %2 -> %1.</term>
+<listitem><para>
+The xfrin module received an update containing multiple rdata changes for the
+same RRset. But the TTLs of these don't match each other. As we combine them
+together, the later one get's overwritten to the earlier one in the sequence.
+</para></listitem>
+</varlistentry>
+
 <varlistentry id="LOGIMPL_ABOVE_MAX_DEBUG">
 <term>LOGIMPL_ABOVE_MAX_DEBUG debug level of %1 is too high and will be set to the maximum of %2</term>
 <listitem><para>
@@ -4103,21 +4243,17 @@ configuration update from the configuration manager.
 </para></listitem>
 </varlistentry>
 
-<varlistentry id="STATS_RECEIVED_REMOVE_COMMAND">
-<term>STATS_RECEIVED_REMOVE_COMMAND received command to remove %1</term>
+<varlistentry id="STATS_RECEIVED_SHOWSCHEMA_ALL_COMMAND">
+<term>STATS_RECEIVED_SHOWSCHEMA_ALL_COMMAND received command to show all statistics schema</term>
 <listitem><para>
-A remove command for the given name was sent to the stats module, and
-the given statistics value will now be removed. It will not appear in
-statistics reports until it appears in a statistics update from a
-module again.
+The stats module received a command to show all statistics schemas of all modules.
 </para></listitem>
 </varlistentry>
 
-<varlistentry id="STATS_RECEIVED_RESET_COMMAND">
-<term>STATS_RECEIVED_RESET_COMMAND received command to reset all statistics</term>
+<varlistentry id="STATS_RECEIVED_SHOWSCHEMA_NAME_COMMAND">
+<term>STATS_RECEIVED_SHOWSCHEMA_NAME_COMMAND received command to show statistics schema for %1</term>
 <listitem><para>
-The stats module received a command to clear all collected statistics.
-The data is cleared until it receives an update from the modules again.
+The stats module received a command to show the specified statistics schema of the specified module.
 </para></listitem>
 </varlistentry>
 
@@ -4168,6 +4304,21 @@ to send its data to the stats module.
 </para></listitem>
 </varlistentry>
 
+<varlistentry id="STATS_STARTING">
+<term>STATS_STARTING starting</term>
+<listitem><para>
+The stats module will be now starting.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="STATS_START_ERROR">
+<term>STATS_START_ERROR stats module error: %1</term>
+<listitem><para>
+An internal error occurred while starting the stats module. The stats
+module will be now shutting down.
+</para></listitem>
+</varlistentry>
+
 <varlistentry id="STATS_STOPPED_BY_KEYBOARD">
 <term>STATS_STOPPED_BY_KEYBOARD keyboard interrupt, shutting down</term>
 <listitem><para>
@@ -4191,39 +4342,28 @@ Please check your installation.
 <term>XFRIN_AXFR_DATABASE_FAILURE AXFR transfer of zone %1 failed: %2</term>
 <listitem><para>
 The AXFR transfer for the given zone has failed due to a database problem.
-The error is shown in the log message.
+The error is shown in the log message.  Note: due to the code structure
+this can only happen for AXFR.
 </para></listitem>
 </varlistentry>
 
-<varlistentry id="XFRIN_AXFR_INTERNAL_FAILURE">
-<term>XFRIN_AXFR_INTERNAL_FAILURE AXFR transfer of zone %1 failed: %2</term>
+<varlistentry id="XFRIN_AXFR_INCONSISTENT_SOA">
+<term>XFRIN_AXFR_INCONSISTENT_SOA AXFR SOAs are inconsistent for %1: %2 expected, %3 received</term>
 <listitem><para>
-The AXFR transfer for the given zone has failed due to an internal
-problem in the bind10 python wrapper library.
-The error is shown in the log message.
-</para></listitem>
-</varlistentry>
-
-<varlistentry id="XFRIN_AXFR_TRANSFER_FAILURE">
-<term>XFRIN_AXFR_TRANSFER_FAILURE AXFR transfer of zone %1 failed: %2</term>
-<listitem><para>
-The AXFR transfer for the given zone has failed due to a protocol error.
-The error is shown in the log message.
-</para></listitem>
-</varlistentry>
-
-<varlistentry id="XFRIN_AXFR_TRANSFER_STARTED">
-<term>XFRIN_AXFR_TRANSFER_STARTED AXFR transfer of zone %1 started</term>
-<listitem><para>
-A connection to the master server has been made, the serial value in
-the SOA record has been checked, and a zone transfer has been started.
-</para></listitem>
-</varlistentry>
-
-<varlistentry id="XFRIN_AXFR_TRANSFER_SUCCESS">
-<term>XFRIN_AXFR_TRANSFER_SUCCESS AXFR transfer of zone %1 succeeded</term>
-<listitem><para>
-The AXFR transfer of the given zone was successfully completed.
+The serial fields of the first and last SOAs of AXFR (including AXFR-style
+IXFR) are not the same.  According to RFC 5936 these two SOAs must be the
+"same" (not only for the serial), but it is still not clear what the
+receiver should do if this condition does not hold.  There was a discussion
+about this at the IETF dnsext wg:
+http://www.ietf.org/mail-archive/web/dnsext/current/msg07908.html
+and the general feeling seems that it would be better to reject the
+transfer if a mismatch is detected.  On the other hand, also as noted
+in that email thread, neither BIND 9 nor NSD performs any comparison
+on the SOAs.  For now, we only check the serials (ignoring other fields)
+and only leave a warning log message when a mismatch is found.  If it
+turns out to happen with a real world primary server implementation
+and that server actually feeds broken data (e.g. mixed versions of
+zone), we can consider a stricter action.
 </para></listitem>
 </varlistentry>
 
@@ -4280,6 +4420,27 @@ shown in the log message.
 </para></listitem>
 </varlistentry>
 
+<varlistentry id="XFRIN_GOT_INCREMENTAL_RESP">
+<term>XFRIN_GOT_INCREMENTAL_RESP got incremental response for %1</term>
+<listitem><para>
+In an attempt of IXFR processing, the begenning SOA of the first difference
+(following the initial SOA that specified the final SOA for all the
+differences) was found.  This means a connection for xfrin tried IXFR
+and really aot a response for incremental updates.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="XFRIN_GOT_NONINCREMENTAL_RESP">
+<term>XFRIN_GOT_NONINCREMENTAL_RESP got nonincremental response for %1</term>
+<listitem><para>
+Non incremental transfer was detected at the "first data" of a transfer,
+which is the RR following the initial SOA.  Non incremental transfer is
+either AXFR or AXFR-style IXFR.  In the latter case, it means that
+in a response to IXFR query the first data is not SOA or its SOA serial
+is not equal to the requested SOA serial.
+</para></listitem>
+</varlistentry>
+
 <varlistentry id="XFRIN_IMPORT_DNS">
 <term>XFRIN_IMPORT_DNS error importing python DNS module: %1</term>
 <listitem><para>
@@ -4305,6 +4466,16 @@ likely means that the msgq daemon has quit or was killed.
 </para></listitem>
 </varlistentry>
 
+<varlistentry id="XFRIN_NOTIFY_UNKNOWN_MASTER">
+<term>XFRIN_NOTIFY_UNKNOWN_MASTER got notification to retransfer zone %1 from %2, expected %3</term>
+<listitem><para>
+The system received a notify for the given zone, but the address it came
+from does not match the master address in the Xfrin configuration. The notify
+is ignored. This may indicate that the configuration for the master is wrong,
+that a wrong machine is sending notifies, or that fake notifies are being sent.
+</para></listitem>
+</varlistentry>
+
 <varlistentry id="XFRIN_RETRANSFER_UNKNOWN_ZONE">
 <term>XFRIN_RETRANSFER_UNKNOWN_ZONE got notification to retransfer unknown zone %1</term>
 <listitem><para>
@@ -4338,6 +4509,38 @@ exception message is printed in the log message.
 </para></listitem>
 </varlistentry>
 
+<varlistentry id="XFRIN_XFR_OTHER_FAILURE">
+<term>XFRIN_XFR_OTHER_FAILURE %1 transfer of zone %2 failed: %3</term>
+<listitem><para>
+The XFR transfer for the given zone has failed due to a problem outside
+of the xfrin module.  Possible reasons are a broken DNS message or failure
+in database connection.  The error is shown in the log message.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="XFRIN_XFR_TRANSFER_FAILURE">
+<term>XFRIN_XFR_TRANSFER_FAILURE %1 transfer of zone %2 failed: %3</term>
+<listitem><para>
+The XFR transfer for the given zone has failed due to a protocol error.
+The error is shown in the log message.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="XFRIN_XFR_TRANSFER_STARTED">
+<term>XFRIN_XFR_TRANSFER_STARTED %1 transfer of zone %2 started</term>
+<listitem><para>
+A connection to the master server has been made, the serial value in
+the SOA record has been checked, and a zone transfer has been started.
+</para></listitem>
+</varlistentry>
+
+<varlistentry id="XFRIN_XFR_TRANSFER_SUCCESS">
+<term>XFRIN_XFR_TRANSFER_SUCCESS %1 transfer of zone %2 succeeded</term>
+<listitem><para>
+The XFR transfer of the given zone was successfully completed.
+</para></listitem>
+</varlistentry>
+
 <varlistentry id="XFROUT_AXFR_TRANSFER_DONE">
 <term>XFROUT_AXFR_TRANSFER_DONE transfer of %1/%2 complete</term>
 <listitem><para>
@@ -4401,6 +4604,14 @@ configuration manager b10-cfgmgr is not running.
 </para></listitem>
 </varlistentry>
 
+<varlistentry id="XFROUT_CONFIG_ERROR">
+<term>XFROUT_CONFIG_ERROR error found in configuration data: %1</term>
+<listitem><para>
+The xfrout process encountered an error when installing the configuration at
+startup time.  Details of the error are included in the log message.
+</para></listitem>
+</varlistentry>
+
 <varlistentry id="XFROUT_FETCH_REQUEST_ERROR">
 <term>XFROUT_FETCH_REQUEST_ERROR socket error while fetching a request from the auth daemon</term>
 <listitem><para>
@@ -4430,6 +4641,17 @@ system and your specific installation.
 </para></listitem>
 </varlistentry>
 
+<varlistentry id="XFROUT_MODULECC_SESSION_ERROR">
+<term>XFROUT_MODULECC_SESSION_ERROR error encountered by configuration/command module: %1</term>
+<listitem><para>
+There was a problem in the lower level module handling configuration and
+control commands.  This could happen for various reasons, but the most likely
+cause is that the configuration database contains a syntax error and xfrout
+failed to start at initialization.  A detailed error message from the module
+will also be displayed.
+</para></listitem>
+</varlistentry>
+
 <varlistentry id="XFROUT_NEW_CONFIG">
 <term>XFROUT_NEW_CONFIG Update xfrout configuration</term>
 <listitem><para>
diff --git a/src/bin/auth/tests/Makefile.am b/src/bin/auth/tests/Makefile.am
index a4bd6fa..d27386e 100644
--- a/src/bin/auth/tests/Makefile.am
+++ b/src/bin/auth/tests/Makefile.am
@@ -67,4 +67,4 @@ run_unittests_LDADD += $(top_builddir)/src/lib/nsas/libnsas.la
 run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
 endif
 
-check_PROGRAMS = $(TESTS)
+noinst_PROGRAMS = $(TESTS)
diff --git a/src/bin/bind10/Makefile.am b/src/bin/bind10/Makefile.am
index 5ec0c9f..69ea256 100644
--- a/src/bin/bind10/Makefile.am
+++ b/src/bin/bind10/Makefile.am
@@ -33,6 +33,7 @@ $(PYTHON_LOGMSGPKG_DIR)/work/bind10_messages.py : bind10_messages.mes
 # this is done here since configure.ac AC_OUTPUT doesn't expand exec_prefix
 bind10: bind10_src.py $(PYTHON_LOGMSGPKG_DIR)/work/bind10_messages.py
 	$(SED) -e "s|@@PYTHONPATH@@|@pyexecdir@|" \
+	       -e "s|@@LIBDIR@@|$(libdir)|" \
 	       -e "s|@@LIBEXECDIR@@|$(pkglibexecdir)|" bind10_src.py >$@
 	chmod a+x $@
 
diff --git a/src/bin/bind10/bind10_src.py.in b/src/bin/bind10/bind10_src.py.in
index 1687cb1..94747f2 100755
--- a/src/bin/bind10/bind10_src.py.in
+++ b/src/bin/bind10/bind10_src.py.in
@@ -579,6 +579,22 @@ class BoB:
         self.start_simple("b10-xfrout", c_channel_env)
 
     def start_xfrin(self, c_channel_env):
+        # XXX: a quick-hack workaround.  xfrin will implicitly use dynamically
+        # loadable data source modules, which will be installed in $(libdir).
+        # On some OSes (including MacOS X and *BSDs) the main process (python)
+        # cannot find the modules unless they are located in a common shared
+        # object path or a path in the (DY)LD_LIBRARY_PATH.  We should seek
+        # a cleaner solution, but for a short term workaround we specify the
+        # path here, unconditionally, and without even bothering which
+        # environment variable should be used.
+        if not "B10_FROM_SOURCE" in os.environ:
+            cur_path = os.getenv('DYLD_LIBRARY_PATH')
+            cur_path = '' if cur_path is None else ':' + cur_path
+            c_channel_env['DYLD_LIBRARY_PATH'] = "@@LIBDIR@@" + cur_path
+
+            cur_path = os.getenv('LD_LIBRARY_PATH')
+            cur_path = '' if cur_path is None else ':' + cur_path
+            c_channel_env['LD_LIBRARY_PATH'] = "@@LIBDIR@@" + cur_path
         self.start_simple("b10-xfrin", c_channel_env)
 
     def start_zonemgr(self, c_channel_env):
diff --git a/src/bin/cfgmgr/plugins/Makefile.am b/src/bin/cfgmgr/plugins/Makefile.am
index 529a4ed..5a4cfef 100644
--- a/src/bin/cfgmgr/plugins/Makefile.am
+++ b/src/bin/cfgmgr/plugins/Makefile.am
@@ -1,11 +1,14 @@
 SUBDIRS = tests
-EXTRA_DIST = README tsig_keys.py tsig_keys.spec
-EXTRA_DIST += logging.spec b10logging.py
+
+EXTRA_DIST = README logging.spec tsig_keys.spec
 
 config_plugindir = @prefix@/share/@PACKAGE@/config_plugins
-config_plugin_DATA = tsig_keys.py tsig_keys.spec
-config_plugin_DATA += b10logging.py logging.spec
+config_plugin_DATA = logging.spec tsig_keys.spec
+
+python_PYTHON = b10logging.py tsig_keys.py
+pythondir = $(config_plugindir)
 
+CLEANFILES = b10logging.pyc tsig_keys.pyc
 CLEANDIRS = __pycache__
 
 clean-local:
diff --git a/src/bin/dhcp6/Makefile.am b/src/bin/dhcp6/Makefile.am
index 805d6bb..690ba5f 100644
--- a/src/bin/dhcp6/Makefile.am
+++ b/src/bin/dhcp6/Makefile.am
@@ -4,9 +4,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin
 AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
 AM_CPPFLAGS += -I$(top_srcdir)/src/lib/cc -I$(top_builddir)/src/lib/cc
-AM_CPPFLAGS += -I$(top_srcdir)/src/lib/asiolink
-AM_CPPFLAGS += -I$(top_builddir)/src/lib/asiolink
-AM_CPPFLAGS += $(BOOST_INCLUDES)
+ AM_CPPFLAGS += $(BOOST_INCLUDES)
 
 AM_CXXFLAGS = $(B10_CXXFLAGS)
 
@@ -31,20 +29,14 @@ spec_config.h: spec_config.h.pre
 
 BUILT_SOURCES = spec_config.h
 pkglibexec_PROGRAMS = b10-dhcp6
-b10_dhcp6_SOURCES = main.cc iface_mgr.cc pkt6.cc dhcp6_srv.cc
-b10_dhcp6_SOURCES += iface_mgr.h pkt6.h dhcp6_srv.h dhcp6.h
-b10_dhcp6_LDADD =  $(top_builddir)/src/lib/datasrc/libdatasrc.la
-b10_dhcp6_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
-b10_dhcp6_LDADD += $(top_builddir)/src/lib/util/libutil.la
-b10_dhcp6_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
-b10_dhcp6_LDADD += $(top_builddir)/src/lib/cc/libcc.la
+
+b10_dhcp6_SOURCES = main.cc iface_mgr.cc dhcp6_srv.cc
+b10_dhcp6_SOURCES += iface_mgr.h dhcp6_srv.h
+
+b10_dhcp6_LDADD = $(top_builddir)/src/lib/dhcp/libdhcp.la
 b10_dhcp6_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
-b10_dhcp6_LDADD += $(top_builddir)/src/lib/asiodns/libasiodns.la
 b10_dhcp6_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
 b10_dhcp6_LDADD += $(top_builddir)/src/lib/log/liblog.la
-b10_dhcp6_LDADD += $(top_builddir)/src/lib/xfr/libxfr.la
-b10_dhcp6_LDADD += $(top_builddir)/src/lib/server_common/libserver_common.la
-b10_dhcp6_LDADD += $(SQLITE_LIBS)
 
 # TODO: config.h.in is wrong because doesn't honor pkgdatadir
 # and can't use @datadir@ because doesn't expand default ${prefix}
diff --git a/src/bin/dhcp6/dhcp6.h b/src/bin/dhcp6/dhcp6.h
deleted file mode 100644
index b5512f3..0000000
--- a/src/bin/dhcp6/dhcp6.h
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright (C) 2006-2011  Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#ifndef DHCP6_H
-#define DHCP6_H
-
-/* DHCPv6 Option codes: */
-
-#define D6O_CLIENTID				1 /* RFC3315 */
-#define D6O_SERVERID				2
-#define D6O_IA_NA				3
-#define D6O_IA_TA				4
-#define D6O_IAADDR				5
-#define D6O_ORO					6
-#define D6O_PREFERENCE				7
-#define D6O_ELAPSED_TIME			8
-#define D6O_RELAY_MSG				9
-/* Option code 10 unassigned. */
-#define D6O_AUTH				11
-#define D6O_UNICAST				12
-#define D6O_STATUS_CODE				13
-#define D6O_RAPID_COMMIT			14
-#define D6O_USER_CLASS				15
-#define D6O_VENDOR_CLASS			16
-#define D6O_VENDOR_OPTS				17
-#define D6O_INTERFACE_ID			18
-#define D6O_RECONF_MSG				19
-#define D6O_RECONF_ACCEPT			20
-#define D6O_SIP_SERVERS_DNS			21 /* RFC3319 */
-#define D6O_SIP_SERVERS_ADDR			22 /* RFC3319 */
-#define D6O_NAME_SERVERS			23 /* RFC3646 */
-#define D6O_DOMAIN_SEARCH			24 /* RFC3646 */
-#define D6O_IA_PD				25 /* RFC3633 */
-#define D6O_IAPREFIX				26 /* RFC3633 */
-#define D6O_NIS_SERVERS				27 /* RFC3898 */
-#define D6O_NISP_SERVERS			28 /* RFC3898 */
-#define D6O_NIS_DOMAIN_NAME			29 /* RFC3898 */
-#define D6O_NISP_DOMAIN_NAME			30 /* RFC3898 */
-#define D6O_SNTP_SERVERS			31 /* RFC4075 */
-#define D6O_INFORMATION_REFRESH_TIME		32 /* RFC4242 */
-#define D6O_BCMCS_SERVER_D			33 /* RFC4280 */
-#define D6O_BCMCS_SERVER_A			34 /* RFC4280 */
-/* 35 is unassigned */
-#define D6O_GEOCONF_CIVIC			36 /* RFC4776 */
-#define D6O_REMOTE_ID				37 /* RFC4649 */
-#define D6O_SUBSCRIBER_ID			38 /* RFC4580 */
-#define D6O_CLIENT_FQDN				39 /* RFC4704 */
-#define D6O_PANA_AGENT				40 /* paa-option */
-#define D6O_NEW_POSIX_TIMEZONE			41 /* RFC4833 */
-#define D6O_NEW_TZDB_TIMEZONE			42 /* RFC4833 */
-#define D6O_ERO					43 /* RFC4994 */
-#define D6O_LQ_QUERY				44 /* RFC5007 */
-#define D6O_CLIENT_DATA				45 /* RFC5007 */
-#define D6O_CLT_TIME				46 /* RFC5007 */
-#define D6O_LQ_RELAY_DATA			47 /* RFC5007 */
-#define D6O_LQ_CLIENT_LINK			48 /* RFC5007 */
-
-/* 
- * Status Codes, from RFC 3315 section 24.4, and RFC 3633, 5007.
- */
-#define STATUS_Success		 0
-#define STATUS_UnspecFail	 1
-#define STATUS_NoAddrsAvail	 2
-#define STATUS_NoBinding	 3
-#define STATUS_NotOnLink	 4 
-#define STATUS_UseMulticast	 5 
-#define STATUS_NoPrefixAvail	 6
-#define STATUS_UnknownQueryType	 7
-#define STATUS_MalformedQuery	 8
-#define STATUS_NotConfigured	 9
-#define STATUS_NotAllowed	10
-
-/* 
- * DHCPv6 message types, defined in section 5.3 of RFC 3315 
- */
-#define DHCPV6_SOLICIT		    1
-#define DHCPV6_ADVERTISE	    2
-#define DHCPV6_REQUEST		    3
-#define DHCPV6_CONFIRM		    4
-#define DHCPV6_RENEW		    5
-#define DHCPV6_REBIND		    6
-#define DHCPV6_REPLY		    7
-#define DHCPV6_RELEASE		    8
-#define DHCPV6_DECLINE		    9
-#define DHCPV6_RECONFIGURE	   10
-#define DHCPV6_INFORMATION_REQUEST 11
-#define DHCPV6_RELAY_FORW	   12
-#define DHCPV6_RELAY_REPL	   13
-#define DHCPV6_LEASEQUERY	   14
-#define DHCPV6_LEASEQUERY_REPLY    15
-
-extern const char *dhcpv6_type_names[];
-extern const int dhcpv6_type_name_max;
-
-/* DUID type definitions (RFC3315 section 9).
- */
-#define DUID_LLT	1
-#define DUID_EN		2
-#define DUID_LL		3
-
-/* Offsets into IA_*'s where Option spaces commence.  */
-#define IA_NA_OFFSET 12 /* IAID, T1, T2, all 4 octets each */
-#define IA_TA_OFFSET  4 /* IAID only, 4 octets */
-#define IA_PD_OFFSET 12 /* IAID, T1, T2, all 4 octets each */
-
-/* Offset into IAADDR's where Option spaces commence. */
-#define IAADDR_OFFSET 24
-
-/* Offset into IAPREFIX's where Option spaces commence. */
-#define IAPREFIX_OFFSET 25
-
-/* Offset into LQ_QUERY's where Option spaces commence. */
-#define LQ_QUERY_OFFSET 17
-
-/* 
- * DHCPv6 well-known multicast addressess, from section 5.1 of RFC 3315 
- */
-#define ALL_DHCP_RELAY_AGENTS_AND_SERVERS "ff02::1:2"
-#define ALL_DHCP_SERVERS "ff05::1:3"
-
-#define DHCP6_CLIENT_PORT 546
-#define DHCP6_SERVER_PORT 547
-
-/*
- * DHCPv6 Retransmission Constants (RFC3315 section 5.5, RFC 5007)
- */
-
-#define SOL_MAX_DELAY     1
-#define SOL_TIMEOUT       1
-#define SOL_MAX_RT      120
-#define REQ_TIMEOUT       1
-#define REQ_MAX_RT       30
-#define REQ_MAX_RC       10
-#define CNF_MAX_DELAY     1
-#define CNF_TIMEOUT       1
-#define CNF_MAX_RT        4
-#define CNF_MAX_RD       10
-#define REN_TIMEOUT      10
-#define REN_MAX_RT      600
-#define REB_TIMEOUT      10
-#define REB_MAX_RT      600
-#define INF_MAX_DELAY     1
-#define INF_TIMEOUT       1
-#define INF_MAX_RT      120
-#define REL_TIMEOUT       1
-#define REL_MAX_RC        5
-#define DEC_TIMEOUT       1
-#define DEC_MAX_RC        5
-#define REC_TIMEOUT       2
-#define REC_MAX_RC        8
-#define HOP_COUNT_LIMIT  32
-#define LQ6_TIMEOUT       1
-#define LQ6_MAX_RT       10
-#define LQ6_MAX_RC        5
-
-/* Leasequery query-types (RFC 5007) */
-
-#define LQ6QT_BY_ADDRESS	1
-#define LQ6QT_BY_CLIENTID	2
-
-/*
- * DUID time starts 2000-01-01.
- * This constant is the number of seconds since 1970-01-01,
- * when the Unix epoch began.
- */
-#define DUID_TIME_EPOCH 946684800
-
-/* Information-Request Time option (RFC 4242) */
-
-#define IRT_DEFAULT	86400
-#define IRT_MINIMUM	600
-
-#endif
diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc
index 4d9244f..ba5afec 100644
--- a/src/bin/dhcp6/dhcp6_srv.cc
+++ b/src/bin/dhcp6/dhcp6_srv.cc
@@ -12,12 +12,18 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-#include "dhcp6/pkt6.h"
+#include "dhcp/dhcp6.h"
+#include "dhcp/pkt6.h"
 #include "dhcp6/iface_mgr.h"
 #include "dhcp6/dhcp6_srv.h"
+#include "dhcp/option6_ia.h"
+#include "dhcp/option6_iaaddr.h"
+#include "asiolink/io_address.h"
 
 using namespace std;
 using namespace isc;
+using namespace isc::dhcp;
+using namespace isc::asiolink;
 
 Dhcpv6Srv::Dhcpv6Srv() {
     cout << "Initialization" << endl;
@@ -25,6 +31,12 @@ Dhcpv6Srv::Dhcpv6Srv() {
     // first call to instance() will create IfaceMgr (it's a singleton)
     // it may throw something if things go wrong
     IfaceMgr::instance();
+
+    /// @todo: instantiate LeaseMgr here once it is imlpemented.
+
+    setServerID();
+
+    shutdown = false;
 }
 
 Dhcpv6Srv::~Dhcpv6Srv() {
@@ -33,23 +45,187 @@ Dhcpv6Srv::~Dhcpv6Srv() {
 
 bool
 Dhcpv6Srv::run() {
-    while (true) {
-        Pkt6* pkt;
+    while (!shutdown) {
+        boost::shared_ptr<Pkt6> query; // client's message
+        boost::shared_ptr<Pkt6> rsp;   // server's response
 
-        pkt = IfaceMgr::instance().receive();
+        query = IfaceMgr::instance().receive();
 
-        if (pkt) {
-            cout << "Received " << pkt->data_len_ << " bytes, echoing back."
-                 << endl;
-            IfaceMgr::instance().send(*pkt);
-            delete pkt;
-        }
+        if (query) {
+            if (!query->unpack()) {
+                cout << "Failed to parse incoming packet" << endl;
+                continue;
+            }
+            switch (query->getType()) {
+            case DHCPV6_SOLICIT:
+                rsp = processSolicit(query);
+                break;
+            case DHCPV6_REQUEST:
+                rsp = processRequest(query);
+                break;
+            case DHCPV6_RENEW:
+                rsp = processRenew(query);
+                break;
+            case DHCPV6_REBIND:
+                rsp = processRebind(query);
+                break;
+            case DHCPV6_CONFIRM:
+                rsp = processConfirm(query);
+                break;
+            case DHCPV6_RELEASE:
+                rsp = processRelease(query);
+                break;
+            case DHCPV6_DECLINE:
+                rsp = processDecline(query);
+                break;
+            case DHCPV6_INFORMATION_REQUEST:
+                rsp = processInfRequest(query);
+                break;
+            default:
+                cout << "Unknown pkt type received:"
+                     << query->getType() << endl;
+            }
 
-	// TODO add support for config session (see src/bin/auth/main.cc)
-	//      so this daemon can be controlled from bob
-        sleep(1);
+            cout << "Received " << query->data_len_ << " bytes packet type="
+                 << query->getType() << endl;
+            cout << query->toText();
+            if (rsp) {
+                rsp->remote_addr_ = query->remote_addr_;
+                rsp->local_addr_ = query->local_addr_;
+                rsp->remote_port_ = DHCP6_CLIENT_PORT;
+                rsp->local_port_ = DHCP6_SERVER_PORT;
+                rsp->ifindex_ = query->ifindex_;
+                rsp->iface_ = query->iface_;
+                cout << "Replying with:" << rsp->getType() << endl;
+                cout << rsp->toText();
+                cout << "----" << endl;
+                if (rsp->pack()) {
+                    cout << "#### pack successful." << endl;
+                }
+                IfaceMgr::instance().send(rsp);
+            }
+        }
 
+        // TODO add support for config session (see src/bin/auth/main.cc)
+        //      so this daemon can be controlled from bob
     }
 
     return (true);
 }
+
+void
+Dhcpv6Srv::setServerID() {
+    /// TODO implement this for real once interface detection is done.
+    /// Use hardcoded server-id for now
+
+    boost::shared_array<uint8_t> srvid(new uint8_t[14]);
+    srvid[0] = 0;
+    srvid[1] = 1; // DUID type 1 = DUID-LLT (see section 9.2 of RFC3315)
+    srvid[2] = 0;
+    srvid[3] = 6; // HW type = ethernet (I think. I'm typing this from my head
+                  // in hotel, without Internet connection)
+    for (int i=4; i<14; i++) {
+        srvid[i]=i-4;
+    }
+    serverid_ = boost::shared_ptr<Option>(new Option(Option::V6,
+                                                     D6O_SERVERID,
+                                                     srvid,
+                                                     0, 14));
+}
+
+boost::shared_ptr<Pkt6>
+Dhcpv6Srv::processSolicit(boost::shared_ptr<Pkt6> solicit) {
+
+    boost::shared_ptr<Pkt6> reply(new Pkt6(DHCPV6_ADVERTISE,
+                                           solicit->getTransid(),
+                                           Pkt6::UDP));
+
+    /// TODO Rewrite this once LeaseManager is implemented.
+
+    // answer client's IA (this is mostly a dummy,
+    // so let's answer only first IA and hope there is only one)
+    boost::shared_ptr<Option> ia_opt = solicit->getOption(D6O_IA_NA);
+    if (ia_opt) {
+        // found IA
+        Option* tmp = ia_opt.get();
+        Option6IA* ia_req = dynamic_cast<Option6IA*>(tmp);
+        if (ia_req) {
+            boost::shared_ptr<Option6IA>
+                ia_rsp(new Option6IA(D6O_IA_NA, ia_req->getIAID()));
+            ia_rsp->setT1(1500);
+            ia_rsp->setT2(2600);
+            boost::shared_ptr<Option6IAAddr>
+                addr(new Option6IAAddr(D6O_IAADDR,
+                                       IOAddress("2001:db8:1234:5678::abcd"),
+                                       5000, 7000));
+            ia_rsp->addOption(addr);
+            reply->addOption(ia_rsp);
+        }
+    }
+
+    // add client-id
+    boost::shared_ptr<Option> clientid = solicit->getOption(D6O_CLIENTID);
+    if (clientid) {
+        reply->addOption(clientid);
+    }
+
+    // add server-id
+    reply->addOption(getServerID());
+    return reply;
+}
+
+boost::shared_ptr<Pkt6>
+Dhcpv6Srv::processRequest(boost::shared_ptr<Pkt6> request) {
+    /// TODO: Implement processRequest() for real
+    boost::shared_ptr<Pkt6> reply = processSolicit(request);
+    reply->setType(DHCPV6_REPLY);
+    return reply;
+}
+
+boost::shared_ptr<Pkt6>
+Dhcpv6Srv::processRenew(boost::shared_ptr<Pkt6> renew) {
+    boost::shared_ptr<Pkt6> reply(new Pkt6(DHCPV6_REPLY,
+                                           renew->getTransid(),
+                                           Pkt6::UDP));
+    return reply;
+}
+
+boost::shared_ptr<Pkt6>
+Dhcpv6Srv::processRebind(boost::shared_ptr<Pkt6> rebind) {
+    boost::shared_ptr<Pkt6> reply(new Pkt6(DHCPV6_REPLY,
+                                           rebind->getTransid(),
+                                           Pkt6::UDP));
+    return reply;
+}
+
+boost::shared_ptr<Pkt6>
+Dhcpv6Srv::processConfirm(boost::shared_ptr<Pkt6> confirm) {
+    boost::shared_ptr<Pkt6> reply(new Pkt6(DHCPV6_REPLY,
+                                           confirm->getTransid(),
+                                           Pkt6::UDP));
+    return reply;
+}
+
+boost::shared_ptr<Pkt6>
+Dhcpv6Srv::processRelease(boost::shared_ptr<Pkt6> release) {
+    boost::shared_ptr<Pkt6> reply(new Pkt6(DHCPV6_REPLY,
+                                           release->getTransid(),
+                                           Pkt6::UDP));
+    return reply;
+}
+
+boost::shared_ptr<Pkt6>
+Dhcpv6Srv::processDecline(boost::shared_ptr<Pkt6> decline) {
+    boost::shared_ptr<Pkt6> reply(new Pkt6(DHCPV6_REPLY,
+                                           decline->getTransid(),
+                                           Pkt6::UDP));
+    return reply;
+}
+
+boost::shared_ptr<Pkt6>
+Dhcpv6Srv::processInfRequest(boost::shared_ptr<Pkt6> infRequest) {
+    boost::shared_ptr<Pkt6> reply(new Pkt6(DHCPV6_REPLY,
+                                           infRequest->getTransid(),
+                                           Pkt6::UDP));
+    return reply;
+}
diff --git a/src/bin/dhcp6/dhcp6_srv.h b/src/bin/dhcp6/dhcp6_srv.h
index a02f5f6..4daef3a 100644
--- a/src/bin/dhcp6/dhcp6_srv.h
+++ b/src/bin/dhcp6/dhcp6_srv.h
@@ -15,26 +15,142 @@
 #ifndef DHCPV6_SRV_H
 #define DHCPV6_SRV_H
 
+#include <boost/shared_ptr.hpp>
+#include <boost/noncopyable.hpp>
+#include "dhcp/pkt6.h"
+#include "dhcp/option.h"
 #include <iostream>
 
 namespace isc {
-    class Dhcpv6Srv {
-    private:
-        // defined private on purpose. We don't want to have more than
-        // one copy
-        Dhcpv6Srv(const Dhcpv6Srv& src);
-        Dhcpv6Srv& operator=(const Dhcpv6Srv& src);
-
-    public:
-        // default constructor
-        Dhcpv6Srv();
-        ~Dhcpv6Srv();
-
-        bool run();
-
-    protected:
-        bool shutdown;
-    };
+
+namespace dhcp {
+/// @brief DHCPv6 server service.
+///
+/// This singleton class represents DHCPv6 server. It contains all
+/// top-level methods and routines necessary for server operation.
+/// In particular, it instantiates IfaceMgr, loads or generates DUID
+/// that is going to be used as server-identifier, receives incoming
+/// packets, processes them, manages leases assignment and generates
+/// appropriate responses.
+class Dhcpv6Srv : public boost::noncopyable {
+
+public:
+    /// @brief Default constructor.
+    ///
+    /// Instantiates necessary services, required to run DHCPv6 server.
+    /// In particular, creates IfaceMgr that will be responsible for
+    /// network interaction. Will instantiate lease manager, and load
+    /// old or create new DUID.
+    Dhcpv6Srv();
+
+    /// @brief Destructor. Used during DHCPv6 service shutdown.
+    ~Dhcpv6Srv();
+
+    /// @brief Returns server-intentifier option
+    ///
+    /// @return server-id option
+    boost::shared_ptr<isc::dhcp::Option>
+    getServerID() { return serverid_; }
+
+    /// @brief Main server processing loop.
+    ///
+    /// Main server processing loop. Receives incoming packets, verifies
+    /// their correctness, generates appropriate answer (if needed) and
+    /// transmits respones.
+    ///
+    /// @return true, if being shut down gracefully, fail if experienced
+    ///         critical error.
+    bool run();
+
+protected:
+    /// @brief Processes incoming SOLICIT and returns response.
+    ///
+    /// Processes received SOLICIT message and verifies that its sender
+    /// should be served. In particular IA, TA and PD options are populated
+    /// with to-be assinged addresses, temporary addresses and delegated
+    /// prefixes, respectively. In the usual 4 message exchange, server is
+    /// expected to respond with ADVERTISE message. However, if client
+    /// requests rapid-commit and server supports it, REPLY will be sent
+    /// instead of ADVERTISE and requested leases will be assigned
+    /// immediately.
+    ///
+    /// @param solicit SOLICIT message received from client
+    ///
+    /// @return ADVERTISE, REPLY message or NULL
+    boost::shared_ptr<Pkt6>
+    processSolicit(boost::shared_ptr<Pkt6> solicit);
+
+    /// @brief Processes incoming REQUEST and returns REPLY response.
+    ///
+    /// Processes incoming REQUEST message and verifies that its sender
+    /// should be served. In particular IA, TA and PD options are populated
+    /// with assinged addresses, temporary addresses and delegated
+    /// prefixes, respectively. Uses LeaseMgr to allocate or update existing
+    /// leases.
+    ///
+    /// @param request a message received from client
+    ///
+    /// @return REPLY message or NULL
+    boost::shared_ptr<Pkt6>
+    processRequest(boost::shared_ptr<Pkt6> request);
+
+    /// @brief Stub function that will handle incoming RENEW messages.
+    ///
+    /// @param renew message received from client
+    boost::shared_ptr<Pkt6>
+    processRenew(boost::shared_ptr<Pkt6> renew);
+
+    /// @brief Stub function that will handle incoming REBIND messages.
+    ///
+    /// @param rebind message received from client
+    boost::shared_ptr<Pkt6>
+    processRebind(boost::shared_ptr<Pkt6> rebind);
+
+    /// @brief Stub function that will handle incoming CONFIRM messages.
+    ///
+    /// @param confirm message received from client
+    boost::shared_ptr<Pkt6>
+    processConfirm(boost::shared_ptr<Pkt6> confirm);
+
+    /// @brief Stub function that will handle incoming RELEASE messages.
+    ///
+    /// @param release message received from client
+    boost::shared_ptr<Pkt6>
+    processRelease(boost::shared_ptr<Pkt6> release);
+
+    /// @brief Stub function that will handle incoming DECLINE messages.
+    ///
+    /// @param decline message received from client
+    boost::shared_ptr<Pkt6>
+    processDecline(boost::shared_ptr<Pkt6> decline);
+
+    /// @brief Stub function that will handle incoming INF-REQUEST messages.
+    ///
+    /// @param infRequest message received from client
+    boost::shared_ptr<Pkt6>
+    processInfRequest(boost::shared_ptr<Pkt6> infRequest);
+
+    /// @brief Sets server-identifier.
+    ///
+    /// This method attempts to set server-identifier DUID. It loads it
+    /// from a file. If file load fails, it generates new DUID using
+    /// interface link-layer addresses (EUI-64) + timestamp (DUID type
+    /// duid-llt, see RFC3315, section 9.2). If there are no suitable
+    /// interfaces present, exception it thrown
+    ///
+    /// @throws isc::Unexpected Failed to read DUID file and no suitable
+    ///         interfaces for new DUID generation are detected.
+    void setServerID();
+
+    /// server DUID (to be sent in server-identifier option)
+    boost::shared_ptr<isc::dhcp::Option> serverid_;
+
+    /// indicates if shutdown is in progress. Setting it to true will
+    /// initiate server shutdown procedure.
+    volatile bool shutdown;
 };
 
+}; // namespace isc::dhcp
+}; // namespace isc
+
 #endif // DHCP6_SRV_H
diff --git a/src/bin/dhcp6/iface_mgr.cc b/src/bin/dhcp6/iface_mgr.cc
index 1e2551a..a96db07 100644
--- a/src/bin/dhcp6/iface_mgr.cc
+++ b/src/bin/dhcp6/iface_mgr.cc
@@ -18,17 +18,18 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
+#include "dhcp/dhcp6.h"
 #include "dhcp6/iface_mgr.h"
-#include "dhcp6/dhcp6.h"
 #include "exceptions/exceptions.h"
 
 using namespace std;
 using namespace isc;
 using namespace isc::asiolink;
+using namespace isc::dhcp;
 
 namespace isc {
 
-// IfaceMgr is a singleton implementation
+/// IfaceMgr is a singleton implementation
 IfaceMgr* IfaceMgr::instance_ = 0;
 
 void
@@ -44,14 +45,16 @@ IfaceMgr::instanceCreate() {
 
 IfaceMgr&
 IfaceMgr::instance() {
-    if (instance_ == 0)
+    if (instance_ == 0) {
         instanceCreate();
+    }
     return (*instance_);
 }
 
 IfaceMgr::Iface::Iface(const std::string& name, int ifindex)
     :name_(name), ifindex_(ifindex), mac_len_(0) {
-    memset(mac_, 0, 20);
+
+    memset(mac_, 0, sizeof(mac_));
 }
 
 std::string
@@ -64,18 +67,22 @@ IfaceMgr::Iface::getFullName() const {
 std::string
 IfaceMgr::Iface::getPlainMac() const {
     ostringstream tmp;
-    for (int i=0; i<mac_len_; i++) {
-        tmp.fill('0');
+    tmp.fill('0');
+    tmp << hex;
+    for (int i = 0; i < mac_len_; i++) {
         tmp.width(2);
-        tmp << (hex) << (int) mac_[i];
-        if (i<mac_len_-1) {
+        tmp << mac_[i];
+        if (i < mac_len_-1) {
             tmp << ":";
         }
     }
     return (tmp.str());
 }
 
-IfaceMgr::IfaceMgr() {
+IfaceMgr::IfaceMgr()
+    :control_buf_len_(CMSG_SPACE(sizeof(struct in6_pktinfo))),
+     control_buf_(new char[control_buf_len_])
+{
 
     cout << "IfaceMgr initialization." << endl;
 
@@ -83,8 +90,8 @@ IfaceMgr::IfaceMgr() {
         // required for sending/receiving packets
         // let's keep it in front, just in case someone
         // wants to send anything during initialization
-        control_buf_len_ = CMSG_SPACE(sizeof(struct in6_pktinfo));
-        control_buf_ = new char[control_buf_len_];
+
+        // control_buf_ = boost::scoped_array<char>();
 
         detectIfaces();
 
@@ -103,11 +110,8 @@ IfaceMgr::IfaceMgr() {
 }
 
 IfaceMgr::~IfaceMgr() {
-    if (control_buf_) {
-        delete [] control_buf_;
-        control_buf_ = 0;
-        control_buf_len_ = 0;
-    }
+    // control_buf_ is deleted automatically (scoped_ptr)
+    control_buf_len_ = 0;
 }
 
 void
@@ -225,18 +229,6 @@ IfaceMgr::getIface(const std::string& ifname) {
     return (NULL); // not found
 }
 
-
-/**
- * Opens UDP/IPv6 socket and binds it to specific address, interface and port.
- *
- * @param ifname name of the interface
- * @param addr address to be bound.
- * @param port UDP port.
- * @param mcast Should multicast address also be bound?
- *
- * @return socket descriptor, if socket creation, binding and multicast
- * group join were all successful. -1 otherwise.
- */
 int
 IfaceMgr::openSocket(const std::string& ifname,
                      const IOAddress& addr,
@@ -321,15 +313,6 @@ IfaceMgr::openSocket(const std::string& ifname,
     return (sock);
 }
 
-/**
- * joins multicast group
- *
- * @param sock socket file descriptor
- * @param ifname name of the interface (DHCPv6 uses link-scoped mc groups)
- * @param mcast multicast address to join (string)
- *
- * @return true if joined successfully, false otherwise
- */
 bool
 IfaceMgr::joinMcast(int sock, const std::string& ifname,
 const std::string & mcast) {
@@ -355,25 +338,14 @@ const std::string & mcast) {
     return (true);
 }
 
-/**
- * Sends UDP packet over IPv6.
- *
- * All parameters for actual transmission are specified in
- * Pkt6 structure itself. That includes destination address,
- * src/dst port and interface over which data will be sent.
- *
- * @param pkt A packet object that is going to be sent.
- *
- * @return True, if transmission was successful. False otherwise.
- */
 bool
-IfaceMgr::send(Pkt6 &pkt) {
+IfaceMgr::send(boost::shared_ptr<Pkt6>& pkt) {
     struct msghdr m;
     struct iovec v;
     int result;
     struct in6_pktinfo *pktinfo;
     struct cmsghdr *cmsg;
-    memset(control_buf_, 0, control_buf_len_);
+    memset(&control_buf_[0], 0, control_buf_len_);
 
     /*
      * Initialize our message header structure.
@@ -386,11 +358,11 @@ IfaceMgr::send(Pkt6 &pkt) {
     sockaddr_in6 to;
     memset(&to, 0, sizeof(to));
     to.sin6_family = AF_INET6;
-    to.sin6_port = htons(pkt.remote_port_);
+    to.sin6_port = htons(pkt->remote_port_);
     memcpy(&to.sin6_addr,
-           pkt.remote_addr_.getAddress().to_v6().to_bytes().data(),
+           pkt->remote_addr_.getAddress().to_v6().to_bytes().data(),
            16);
-    to.sin6_scope_id = pkt.ifindex_;
+    to.sin6_scope_id = pkt->ifindex_;
 
     m.msg_name = &to;
     m.msg_namelen = sizeof(to);
@@ -400,8 +372,8 @@ IfaceMgr::send(Pkt6 &pkt) {
      * "scatter-gather" stuff... we only have a single chunk
      * of data to send, so we declare a single vector entry.)
      */
-    v.iov_base = (char *) &pkt.data_[0];
-    v.iov_len = pkt.data_len_;
+    v.iov_base = (char *) &pkt->data_[0];
+    v.iov_len = pkt->data_len_;
     m.msg_iov = &v;
     m.msg_iovlen = 1;
 
@@ -413,7 +385,7 @@ IfaceMgr::send(Pkt6 &pkt) {
      * source address if we wanted, but we can safely let the
      * kernel decide what that should be.
      */
-    m.msg_control = control_buf_;
+    m.msg_control = &control_buf_[0];
     m.msg_controllen = control_buf_len_;
     cmsg = CMSG_FIRSTHDR(&m);
     cmsg->cmsg_level = IPPROTO_IPV6;
@@ -421,7 +393,7 @@ IfaceMgr::send(Pkt6 &pkt) {
     cmsg->cmsg_len = CMSG_LEN(sizeof(*pktinfo));
     pktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
     memset(pktinfo, 0, sizeof(*pktinfo));
-    pktinfo->ipi6_ifindex = pkt.ifindex_;
+    pktinfo->ipi6_ifindex = pkt->ifindex_;
     m.msg_controllen = cmsg->cmsg_len;
 
     result = sendmsg(sendsock_, &m, 0);
@@ -430,26 +402,16 @@ IfaceMgr::send(Pkt6 &pkt) {
     }
     cout << "Sent " << result << " bytes." << endl;
 
-    cout << "Sent " << pkt.data_len_ << " bytes over "
-         << pkt.iface_ << "/" << pkt.ifindex_ << " interface: "
-         << " dst=" << pkt.remote_addr_.toText()
-         << ", src=" << pkt.local_addr_.toText()
+    cout << "Sent " << pkt->data_len_ << " bytes over "
+         << pkt->iface_ << "/" << pkt->ifindex_ << " interface: "
+         << " dst=" << pkt->remote_addr_.toText()
+         << ", src=" << pkt->local_addr_.toText()
          << endl;
 
     return (result);
 }
 
-
-/**
- * Attempts to receive UDP/IPv6 packet over open sockets.
- *
- * TODO Start using select() and add timeout to be able
- * to not wait infinitely, but rather do something useful
- * (e.g. remove expired leases)
- *
- * @return Object prepresenting received packet.
- */
-Pkt6*
+boost::shared_ptr<Pkt6>
 IfaceMgr::receive() {
     struct msghdr m;
     struct iovec v;
@@ -458,7 +420,7 @@ IfaceMgr::receive() {
     struct in6_pktinfo* pktinfo;
     struct sockaddr_in6 from;
     struct in6_addr to_addr;
-    Pkt6* pkt;
+    boost::shared_ptr<Pkt6> pkt;
     char addr_str[INET6_ADDRSTRLEN];
 
     try {
@@ -469,13 +431,13 @@ IfaceMgr::receive() {
         // we use larger buffer. This buffer limit is checked
         // during reception (see iov_len below), so we are
         // safe
-        pkt = new Pkt6(65536);
+        pkt = boost::shared_ptr<Pkt6>(new Pkt6(65536));
     } catch (const std::exception& ex) {
         cout << "Failed to create new packet." << endl;
-        return (0);
+        return (boost::shared_ptr<Pkt6>()); // NULL
     }
 
-    memset(control_buf_, 0, control_buf_len_);
+    memset(&control_buf_[0], 0, control_buf_len_);
 
     memset(&from, 0, sizeof(from));
     memset(&to_addr, 0, sizeof(to_addr));
@@ -509,7 +471,7 @@ IfaceMgr::receive() {
      * information (when we initialized the interface), so we
      * should get the destination address from that.
      */
-    m.msg_control = control_buf_;
+    m.msg_control = &control_buf_[0];
     m.msg_controllen = control_buf_len_;
 
     result = recvmsg(recvsock_, &m, 0);
@@ -537,20 +499,20 @@ IfaceMgr::receive() {
         }
         if (!found_pktinfo) {
             cout << "Unable to find pktinfo" << endl;
-            delete pkt;
-            return (0);
+            return (boost::shared_ptr<Pkt6>()); // NULL
         }
     } else {
         cout << "Failed to receive data." << endl;
-        delete pkt;
-        return (0);
+        return (boost::shared_ptr<Pkt6>()); // NULL
     }
 
     // That's ugly.
     // TODO add IOAddress constructor that will take struct in6_addr*
+    // TODO: there's from_bytes() method added in IOAddress. Use it!
     inet_ntop(AF_INET6, &to_addr, addr_str,INET6_ADDRSTRLEN);
     pkt->local_addr_ = IOAddress(string(addr_str));
 
+    // TODO: there's from_bytes() method added in IOAddress. Use it!
     inet_ntop(AF_INET6, &from.sin6_addr, addr_str, INET6_ADDRSTRLEN);
     pkt->remote_addr_ = IOAddress(string(addr_str));
 
@@ -562,8 +524,7 @@ IfaceMgr::receive() {
     } else {
         cout << "Received packet over unknown interface (ifindex="
              << pkt->ifindex_ << ")." << endl;
-        delete pkt;
-        return (0);
+        return (boost::shared_ptr<Pkt6>()); // NULL
     }
 
     pkt->data_len_ = result;
diff --git a/src/bin/dhcp6/iface_mgr.h b/src/bin/dhcp6/iface_mgr.h
index 39061da..249c7ef 100644
--- a/src/bin/dhcp6/iface_mgr.h
+++ b/src/bin/dhcp6/iface_mgr.h
@@ -16,88 +16,214 @@
 #define IFACE_MGR_H
 
 #include <list>
-#include "io_address.h"
-#include "dhcp6/pkt6.h"
+#include <boost/shared_ptr.hpp>
+#include <boost/scoped_array.hpp>
+#include <boost/noncopyable.hpp>
+#include "asiolink/io_address.h"
+#include "dhcp/pkt6.h"
 
 namespace isc {
 
-    /**
-     * IfaceMgr is an interface manager class that detects available network
-     * interfaces, configured addresses, link-local addresses, and provides
-     * API for using sockets.
-     *
-     */
-    class IfaceMgr {
-    public:
-        typedef std::list<isc::asiolink::IOAddress> Addr6Lst;
-        struct Iface { // TODO: could be a class as well
-            std::string name_; // network interface name
-            int ifindex_; // interface index (a value that uniquely indentifies
-                          // an interface
-            Addr6Lst addrs_;
-            char mac_[20]; // Infiniband used 20 bytes indentifiers
-            int mac_len_;
-
-            Iface(const std::string& name, int ifindex);
-            std::string getFullName() const;
-            std::string getPlainMac() const;
-
-            int sendsock_; // socket used to sending data
-            int recvsock_; // socket used for receiving data
-
-            // next field is not needed, let's keep it in cointainers
-        };
-
-        // TODO performance improvement: we may change this into
-        //      2 maps (ifindex-indexed and name-indexed) and
-        //      also hide it (make it public make tests easier for now)
-        typedef std::list<Iface> IfaceLst;
-
-        static IfaceMgr& instance();
-
-        Iface * getIface(int ifindex);
-        Iface * getIface(const std::string& ifname);
-
-        void printIfaces(std::ostream& out = std::cout);
-
-        bool send(Pkt6& pkt);
-        Pkt6* receive();
-
-        // don't use private, we need derived classes in tests
-    protected:
-        IfaceMgr(); // don't create IfaceMgr directly, use instance() method
-        ~IfaceMgr();
-
-        void detectIfaces();
-
-        int openSocket(const std::string& ifname,
-                       const isc::asiolink::IOAddress& addr,
-                       int port);
-
-        // TODO: having 2 maps (ifindex->iface and ifname->iface would)
-        //      probably be better for performance reasons
-        IfaceLst ifaces_;
-
-        static IfaceMgr * instance_;
-
-        // TODO: Also keep this interface on Iface once interface detection
-        // is implemented. We may need it e.g. to close all sockets on
-        // specific interface
-        int recvsock_; // TODO: should be fd_set eventually, but we have only
-        int sendsock_; // 2 sockets for now. Will do for until next release
-        // we can't use the same socket, as receiving socket
-        // is bound to multicast address. And we all know what happens
-        // to people who try to use multicast as source address.
-
-        char * control_buf_;
-        int control_buf_len_;
-
-    private:
-        bool openSockets();
-        static void instanceCreate();
-        bool joinMcast(int sock, const std::string& ifname,
-                       const std::string& mcast);
+namespace dhcp {
+/// @brief handles network interfaces, transmission and reception
+///
+/// IfaceMgr is an interface manager class that detects available network
+/// interfaces, configured addresses, link-local addresses, and provides
+/// API for using sockets.
+///
+class IfaceMgr : public boost::noncopyable {
+public:
+    /// type that defines list of addresses
+    typedef std::list<isc::asiolink::IOAddress> Addr6Lst;
+
+    /// maximum MAC address length (Infiniband uses 20 bytes)
+    static const unsigned int MAX_MAC_LEN = 20;
+
+    /// @brief represents a single network interface
+    ///
+    /// Iface structure represents network interface with all useful
+    /// information, like name, interface index, MAC address and
+    /// list of assigned addresses
+    struct Iface {
+        /// constructor
+        Iface(const std::string& name, int ifindex);
+
+        /// returns full interface name in format ifname/ifindex
+        std::string getFullName() const;
+
+        /// returns link-layer address a plain text
+        std::string getPlainMac() const;
+
+        /// network interface name
+        std::string name_;
+
+        /// interface index (a value that uniquely indentifies an interface)
+        int ifindex_;
+
+        /// list of assigned addresses
+        Addr6Lst addrs_;
+
+        /// link-layer address
+        uint8_t mac_[MAX_MAC_LEN];
+
+        /// length of link-layer address (usually 6)
+        int mac_len_;
+
+        /// socket used to sending data
+        int sendsock_;
+
+        /// socket used for receiving data
+        int recvsock_;
     };
+
+    // TODO performance improvement: we may change this into
+    //      2 maps (ifindex-indexed and name-indexed) and
+    //      also hide it (make it public make tests easier for now)
+
+    /// type that holds a list of interfaces
+    typedef std::list<Iface> IfaceLst;
+
+    /// IfaceMgr is a singleton class. This method returns reference
+    /// to its sole instance.
+    ///
+    /// @return the only existing instance of interface manager
+    static IfaceMgr& instance();
+
+    /// @brief Returns interface with specified interface index
+    ///
+    /// @param ifindex index of searched interface
+    ///
+    /// @return interface with requested index (or NULL if no such
+    ///         interface is present)
+    ///
+    Iface*
+    getIface(int ifindex);
+
+    /// @brief Returns interface with specified interface name
+    ///
+    /// @param ifname name of searched interface
+    ///
+    /// @return interface with requested name (or NULL if no such
+    ///         interface is present)
+    ///
+    Iface*
+    getIface(const std::string& ifname);
+
+    /// debugging method that prints out all available interfaces
+    ///
+    /// @param out specifies stream to print list of interfaces to
+    void
+    printIfaces(std::ostream& out = std::cout);
+
+    /// @brief Sends a packet.
+    ///
+    /// Sends a packet. All parameters for actual transmission are specified in
+    /// Pkt6 structure itself. That includes destination address, src/dst port
+    /// and interface over which data will be sent.
+    ///
+    /// @param pkt packet to be sent
+    ///
+    /// @return true if sending was successful
+    bool
+    send(boost::shared_ptr<Pkt6>& pkt);
+
+    /// @brief Tries to receive packet over open sockets.
+    ///
+    /// Attempts to receive a single packet of any of the open sockets.
+    /// If reception is successful and all information about its sender
+    /// are obtained, Pkt6 object is created and returned.
+    ///
+    /// TODO Start using select() and add timeout to be able
+    /// to not wait infinitely, but rather do something useful
+    /// (e.g. remove expired leases)
+    ///
+    /// @return Pkt6 object representing received packet (or NULL)
+    boost::shared_ptr<Pkt6> receive();
+
+    // don't use private, we need derived classes in tests
+protected:
+
+    /// @brief Protected constructor.
+    ///
+    /// Protected constructor. This is a singleton class. We don't want
+    /// anyone to create instances of IfaceMgr. Use instance() method
+    IfaceMgr();
+
+    ~IfaceMgr();
+
+    /// @brief Detects network interfaces.
+    ///
+    /// This method will eventually detect available interfaces. For now
+    /// it offers stub implementation. First interface name and link-local
+    /// IPv6 address is read from intefaces.txt file.
+    void
+    detectIfaces();
+
+    ///
+    /// Opens UDP/IPv6 socket and binds it to address, interface and port.
+    ///
+    /// @param ifname name of the interface
+    /// @param addr address to be bound.
+    /// @param port UDP port.
+    ///
+    /// @return socket descriptor, if socket creation, binding and multicast
+    /// group join were all successful. -1 otherwise.
+    int openSocket(const std::string& ifname,
+                   const isc::asiolink::IOAddress& addr,
+                   int port);
+
+    // TODO: having 2 maps (ifindex->iface and ifname->iface would)
+    //      probably be better for performance reasons
+
+    /// List of available interfaces
+    IfaceLst ifaces_;
+
+    /// a pointer to a sole instance of this class (a singleton)
+    static IfaceMgr * instance_;
+
+    // TODO: Also keep this interface on Iface once interface detection
+    // is implemented. We may need it e.g. to close all sockets on
+    // specific interface
+    int recvsock_; // TODO: should be fd_set eventually, but we have only
+    int sendsock_; // 2 sockets for now. Will do for until next release
+    // we can't use the same socket, as receiving socket
+    // is bound to multicast address. And we all know what happens
+    // to people who try to use multicast as source address.
+
+    /// length of the control_buf_ array
+    int control_buf_len_;
+
+    /// control-buffer, used in transmission and reception
+    boost::scoped_array<char> control_buf_;
+
+private:
+    /// Opens sockets on detected interfaces.
+    bool
+    openSockets();
+
+    /// creates a single instance of this class (a singleton implementation)
+    static void
+    instanceCreate();
+
+    /// @brief Joins IPv6 multicast group on a socket.
+    ///
+    /// Socket must be created and bound to an address. Note that this
+    /// address is different than the multicast address. For example DHCPv6
+    /// server should bind its socket to link-local address (fe80::1234...)
+    /// and later join ff02::1:2 multicast group.
+    ///
+    /// @param sock socket fd (socket must be bound)
+    /// @param ifname interface name (for link-scoped multicast groups)
+    /// @param mcast multicast address to join (e.g. "ff02::1:2")
+    ///
+    /// @return true if multicast join was successful
+    ///
+    bool
+    joinMcast(int sock, const std::string& ifname,
+              const std::string& mcast);
 };
 
+}; // namespace isc::dhcp
+}; // namespace isc
+
 #endif
diff --git a/src/bin/dhcp6/main.cc b/src/bin/dhcp6/main.cc
index 95d2261..5323811 100644
--- a/src/bin/dhcp6/main.cc
+++ b/src/bin/dhcp6/main.cc
@@ -26,8 +26,11 @@
 #include <iostream>
 
 #include <exceptions/exceptions.h>
+#if 0
+// TODO cc is not used yet. It should be eventually
 #include <cc/session.h>
 #include <config/ccsession.h>
+#endif
 
 #include <util/buffer.h>
 #include <log/dummylog.h>
@@ -37,12 +40,9 @@
 
 using namespace std;
 using namespace isc::util;
-using namespace isc::data;
-using namespace isc::cc;
-using namespace isc::config;
-using namespace isc::util;
 
 using namespace isc;
+using namespace isc::dhcp;
 
 namespace {
 
@@ -97,8 +97,6 @@ main(int argc, char* argv[]) {
             specfile = string(DHCP6_SPECFILE_LOCATION);
         }
 
-        // auth_server = new AuthSrv(cache, xfrout_client);
-        // auth_server->setVerbose(verbose_mode);
         cout << "[b10-dhcp6] Initiating DHCPv6 operation." << endl;
 
         Dhcpv6Srv* srv = new Dhcpv6Srv();
diff --git a/src/bin/dhcp6/pkt6.cc b/src/bin/dhcp6/pkt6.cc
deleted file mode 100644
index 5dcab86..0000000
--- a/src/bin/dhcp6/pkt6.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-
-#include "dhcp6/dhcp6.h"
-#include "dhcp6/pkt6.h"
-#include <iostream>
-
-namespace isc {
-
-///
-/// constructor
-///
-/// \param dataLen - length of the data to be allocated
-///
-Pkt6::Pkt6(int dataLen)
-    :local_addr_("::"),
-     remote_addr_("::") {
-    try {
-	data_ = boost::shared_array<char>(new char[dataLen]);
-	data_len_ = dataLen;
-    } catch (const std::exception& ex) {
-	// TODO move to LOG_FATAL()
-	// let's continue with empty pkt for now
-        std::cout << "Failed to allocate " << dataLen << " bytes."
-                  << std::endl;
-        data_len_ = 0;
-    }
-}
-
-Pkt6::~Pkt6() {
-    // no need to delete anything shared_ptr will take care of data_
-}
-
-};
diff --git a/src/bin/dhcp6/pkt6.h b/src/bin/dhcp6/pkt6.h
deleted file mode 100644
index 9a14d92..0000000
--- a/src/bin/dhcp6/pkt6.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#ifndef PKT6_H
-#define PKT6_H
-
-#include <iostream>
-#include <boost/shared_array.hpp>
-#include "io_address.h"
-
-namespace isc {
-
-    class Pkt6 {
-    public:
-        Pkt6(int len);
-        ~Pkt6();
-
-        // XXX: probably need getter/setter wrappers
-        //      and hide fields as protected
-        // buffer that holds memory. It is shared_array as options may
-        // share pointer to this buffer
-        boost::shared_array<char> data_;
-
-        // length of the data
-        int data_len_;
-
-        // local address (destination if receiving packet, source if sending packet)
-        isc::asiolink::IOAddress local_addr_;
-
-        // remote address (source if receiving packet, destination if sending packet)
-        isc::asiolink::IOAddress remote_addr_;
-
-        // name of the network interface the packet was received/to be sent over
-        std::string iface_;
-
-        // interface index (each network interface has assigned unique ifindex
-        // it is functional equvalent of name, but sometimes more useful, e.g.
-        // when using crazy systems that allow spaces in interface names (Windows)
-        int ifindex_;
-
-        // local TDP or UDP port
-        int local_port_;
-
-        // remote TCP or UDP port
-        int remote_port_;
-
-        // XXX: add *a lot* here
-    };
-}
-
-#endif
diff --git a/src/bin/dhcp6/tests/Makefile.am b/src/bin/dhcp6/tests/Makefile.am
index ae9d8e3..985368e 100644
--- a/src/bin/dhcp6/tests/Makefile.am
+++ b/src/bin/dhcp6/tests/Makefile.am
@@ -45,11 +45,9 @@ if HAVE_GTEST
 
 TESTS += dhcp6_unittests
 
-dhcp6_unittests_SOURCES = ../pkt6.h ../pkt6.cc
-dhcp6_unittests_SOURCES += ../iface_mgr.h ../iface_mgr.cc
+dhcp6_unittests_SOURCES = ../iface_mgr.h ../iface_mgr.cc
 dhcp6_unittests_SOURCES += ../dhcp6_srv.h ../dhcp6_srv.cc
 dhcp6_unittests_SOURCES += dhcp6_unittests.cc
-dhcp6_unittests_SOURCES += pkt6_unittest.cc
 dhcp6_unittests_SOURCES += iface_mgr_unittest.cc
 dhcp6_unittests_SOURCES += dhcp6_srv_unittest.cc
 
@@ -58,8 +56,7 @@ dhcp6_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
 dhcp6_unittests_LDADD = $(GTEST_LDADD)
 dhcp6_unittests_LDADD += $(SQLITE_LIBS)
 dhcp6_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
-dhcp6_unittests_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
-dhcp6_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.la
+dhcp6_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libdhcp.la
 dhcp6_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 dhcp6_unittests_LDADD += $(top_builddir)/src/lib/log/liblog.la
 endif
diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
index 96c767e..f9a1d9d 100644
--- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
+++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
@@ -19,13 +19,33 @@
 #include <arpa/inet.h>
 #include <gtest/gtest.h>
 
-
+#include "dhcp/dhcp6.h"
 #include "dhcp6/dhcp6_srv.h"
+#include "dhcp/option6_ia.h"
 
 using namespace std;
 using namespace isc;
+using namespace isc::dhcp;
+
+// namespace has to be named, because friends are defined in Dhcpv6Srv class
+// Maybe it should be isc::test?
+namespace test {
+
+class NakedDhcpv6Srv: public Dhcpv6Srv {
+    // "naked" Interface Manager, exposes internal fields
+public:
+    NakedDhcpv6Srv() { }
+
+    boost::shared_ptr<Pkt6>
+    processSolicit(boost::shared_ptr<Pkt6>& request) {
+        return Dhcpv6Srv::processSolicit(request);
+    }
+    boost::shared_ptr<Pkt6>
+    processRequest(boost::shared_ptr<Pkt6>& request) {
+        return Dhcpv6Srv::processRequest(request);
+    }
+};
 
-namespace {
 class Dhcpv6SrvTest : public ::testing::Test {
 public:
     Dhcpv6SrvTest() {
@@ -33,21 +53,94 @@ public:
 };
 
 TEST_F(Dhcpv6SrvTest, basic) {
-    // there's almost no code now. What's there provides echo capability 
+    // there's almost no code now. What's there provides echo capability
     // that is just a proof of concept and will be removed soon
     // No need to thoroughly test it
 
     // srv has stubbed interface detection. It will read
     // interfaces.txt instead. It will pretend to have detected
     // fe80::1234 link-local address on eth0 interface. Obviously
-
     // an attempt to bind this socket will fail.
     EXPECT_NO_THROW( {
         Dhcpv6Srv * srv = new Dhcpv6Srv();
 
-	delete srv;
-	});
-    
+        delete srv;
+        });
+
+}
+
+TEST_F(Dhcpv6SrvTest, Solicit_basic) {
+    NakedDhcpv6Srv * srv = 0;
+    EXPECT_NO_THROW( srv = new NakedDhcpv6Srv(); );
+
+    // a dummy content for client-id
+    boost::shared_array<uint8_t> clntDuid(new uint8_t[32]);
+    for (int i=0; i<32; i++)
+        clntDuid[i] = 100+i;
+
+    boost::shared_ptr<Pkt6> sol =
+        boost::shared_ptr<Pkt6>(new Pkt6(DHCPV6_SOLICIT,
+                                         1234, Pkt6::UDP));
+
+    boost::shared_ptr<Option6IA> ia =
+        boost::shared_ptr<Option6IA>(new Option6IA(D6O_IA_NA, 234));
+    ia->setT1(1501);
+    ia->setT2(2601);
+    sol->addOption(ia);
+
+    // Let's not send address in solicit yet
+    // boost::shared_ptr<Option6IAAddr> addr(new Option6IAAddr(D6O_IAADDR,
+    //    IOAddress("2001:db8:1234:ffff::ffff"), 5001, 7001));
+    // ia->addOption(addr);
+    // sol->addOption(ia);
+
+    // constructed very simple SOLICIT message with:
+    // - client-id option (mandatory)
+    // - IA option (a request for address, without any addresses)
+
+    // expected returned ADVERTISE message:
+    // - copy of client-id
+    // - server-id
+    // - IA that includes IAADDR
+
+    boost::shared_ptr<Option> clientid =
+        boost::shared_ptr<Option>(new Option(Option::V6, D6O_CLIENTID,
+                                             clntDuid, 0, 16));
+    sol->addOption(clientid);
+
+    boost::shared_ptr<Pkt6> reply = srv->processSolicit(sol);
+
+    // check if we get response at all
+    ASSERT_TRUE( reply != boost::shared_ptr<Pkt6>() );
+
+    EXPECT_EQ( DHCPV6_ADVERTISE, reply->getType() );
+    EXPECT_EQ( 1234, reply->getTransid() );
+
+    boost::shared_ptr<Option> tmp = reply->getOption(D6O_IA_NA);
+    ASSERT_TRUE( tmp );
+
+    Option6IA * reply_ia = dynamic_cast<Option6IA*> ( tmp.get() );
+    EXPECT_EQ( 234, reply_ia->getIAID() );
+
+    // check that there's an address included
+    EXPECT_TRUE( reply_ia->getOption(D6O_IAADDR));
+
+    // check that server included our own client-id
+    tmp = reply->getOption(D6O_CLIENTID);
+    ASSERT_TRUE( tmp );
+    EXPECT_EQ(clientid->getType(), tmp->getType() );
+    ASSERT_EQ(clientid->len(), tmp->len() );
+    EXPECT_FALSE(memcmp(clientid->getData(), tmp->getData(), tmp->len() ) );
+    // check that server included its server-id
+    tmp = reply->getOption(D6O_SERVERID);
+    EXPECT_EQ(tmp->getType(), srv->getServerID()->getType() );
+    ASSERT_EQ(tmp->len(),  srv->getServerID()->len() );
+    EXPECT_FALSE( memcmp(tmp->getData(), srv->getServerID()->getData(),
+                      tmp->len()) );
+
+    // more checks to be implemented
+    delete srv;
+
 }
 
 }
diff --git a/src/bin/dhcp6/tests/iface_mgr_unittest.cc b/src/bin/dhcp6/tests/iface_mgr_unittest.cc
index c9a9d72..5ce73f8 100644
--- a/src/bin/dhcp6/tests/iface_mgr_unittest.cc
+++ b/src/bin/dhcp6/tests/iface_mgr_unittest.cc
@@ -21,12 +21,16 @@
 #include <gtest/gtest.h>
 
 #include "io_address.h"
-#include "dhcp6/pkt6.h"
+#include "dhcp/pkt6.h"
 #include "dhcp6/iface_mgr.h"
 
 using namespace std;
 using namespace isc;
 using namespace isc::asiolink;
+using namespace isc::dhcp;
+
+// name of loopback interface detection
+char LOOPBACK[32] = "lo";
 
 namespace {
 const char* const INTERFACE_FILE = TEST_DATA_BUILDDIR "/interfaces.txt";
@@ -54,6 +58,113 @@ public:
     }
 };
 
+// We need some known interface to work reliably. Loopback interface
+// is named lo on Linux and lo0 on BSD boxes. We need to find out
+// which is available. This is not a real test, but rather a workaround
+// that will go away when interface detection is implemented.
+
+// NOTE: At this stage of development, write access to current directory
+// during running tests is required.
+TEST_F(IfaceMgrTest, loDetect) {
+
+    unlink("interfaces.txt");
+
+    ofstream interfaces("interfaces.txt", ios::ate);
+    interfaces << "lo ::1";
+    interfaces.close();
+
+    NakedIfaceMgr * ifacemgr = new NakedIfaceMgr();
+    IOAddress loAddr("::1");
+    IOAddress mcastAddr("ff02::1:2");
+
+    // bind multicast socket to port 10547
+    int socket1 = ifacemgr->openSocket("lo", mcastAddr, 10547);
+    // this fails on BSD (there's no lo interface there)
+
+    // poor man's interface dection
+    // it will go away as soon as proper interface detection
+    // is implemented
+    if (socket1>0) {
+        cout << "This is Linux, using lo as loopback." << endl;
+        close(socket1);
+    } else {
+        // this fails on Linux and succeeds on BSD
+        socket1 = ifacemgr->openSocket("lo0", mcastAddr, 10547);
+        if (socket1>0) {
+            sprintf(LOOPBACK, "lo0");
+            cout << "This is BSD, using lo0 as loopback." << endl;
+            close(socket1);
+        } else {
+            cout << "Failed to detect loopback interface. Neither "
+                 << "lo or lo0 worked. I give up." << endl;
+            ASSERT_TRUE(false);
+        }
+    }
+
+    delete ifacemgr;
+}
+
+// uncomment this test to create packet writer. It will
+// write incoming DHCPv6 packets as C arrays. That is useful
+// for generating test sequences based on actual traffic
+//
+// TODO: this potentially should be moved to a separate tool
+//
+
+#if 0
+TEST_F(IfaceMgrTest, dhcp6Sniffer) {
+    // testing socket operation in a portable way is tricky
+    // without interface detection implemented
+
+    unlink("interfaces.txt");
+
+    ofstream interfaces("interfaces.txt", ios::ate);
+    interfaces << "eth0 fe80::21e:8cff:fe9b:7349";
+    interfaces.close();
+
+    NakedIfaceMgr * ifacemgr = new NakedIfaceMgr();
+
+    Pkt6 * pkt = 0;
+    int cnt = 0;
+    cout << "---8X-----------------------------------------" << endl;
+    while (true) {
+        pkt = ifacemgr->receive();
+
+        cout << "// Received " << pkt->data_len_ << " bytes packet:" << endl;
+        cout << "Pkt6 *capture" << cnt++ << "() {" << endl;
+        cout << "    Pkt6* pkt;" << endl;
+        cout << "    pkt = new Pkt6(" << pkt->data_len_ << ");" << endl;
+        cout << "    pkt->remote_port_ = " << pkt-> remote_port_ << ";" << endl;
+        cout << "    pkt->remote_addr_ = IOAddress(\""
+             << pkt->remote_addr_.toText() << "\");" << endl;
+        cout << "    pkt->local_port_ = " << pkt-> local_port_ << ";" << endl;
+        cout << "    pkt->local_addr_ = IOAddress(\""
+             << pkt->local_addr_.toText() << "\");" << endl;
+        cout << "    pkt->ifindex_ = " << pkt->ifindex_ << ";" << endl;
+        cout << "    pkt->iface_ = \"" << pkt->iface_ << "\";" << endl;
+
+        // TODO it is better to declare an array and then memcpy it to
+        // packet.
+        for (int i=0; i< pkt->data_len_; i++) {
+            cout << "    pkt->data_[" << i << "]="
+                 << (int)(unsigned char)pkt->data_[i] << "; ";
+            if (!(i%4))
+                cout << endl;
+        }
+        cout << endl;
+        cout << "    return (pkt);" << endl;
+        cout << "}" << endl << endl;
+
+        delete pkt;
+    }
+    cout << "---8X-----------------------------------------" << endl;
+
+    // never happens. Infinite loop is infinite
+    delete pkt;
+    delete ifacemgr;
+}
+#endif
+
 TEST_F(IfaceMgrTest, basic) {
     // checks that IfaceManager can be instantiated
 
@@ -72,23 +183,34 @@ TEST_F(IfaceMgrTest, ifaceClass) {
 
 }
 
-// TODO: Implement getPlainMac() test as soon as interface detection is implemented.
+// TODO: Implement getPlainMac() test as soon as interface detection
+// is implemented.
 TEST_F(IfaceMgrTest, getIface) {
 
     cout << "Interface checks. Please ignore socket binding errors." << endl;
     NakedIfaceMgr * ifacemgr = new NakedIfaceMgr();
 
     // interface name, ifindex
-    IfaceMgr::Iface iface1("lo", 1);
+    IfaceMgr::Iface iface1("lo1", 1);
     IfaceMgr::Iface iface2("eth5", 2);
     IfaceMgr::Iface iface3("en3", 5);
     IfaceMgr::Iface iface4("e1000g0", 3);
 
+    // note: real interfaces may be detected as well
     ifacemgr->getIfacesLst().push_back(iface1);
     ifacemgr->getIfacesLst().push_back(iface2);
     ifacemgr->getIfacesLst().push_back(iface3);
     ifacemgr->getIfacesLst().push_back(iface4);
 
+    cout << "There are " << ifacemgr->getIfacesLst().size()
+         << " interfaces." << endl;
+    for (IfaceMgr::IfaceLst::iterator iface=ifacemgr->getIfacesLst().begin();
+         iface != ifacemgr->getIfacesLst().end();
+         ++iface) {
+        cout << "  " << iface->name_ << "/" << iface->ifindex_ << endl;
+    }
+
+
     // check that interface can be retrieved by ifindex
     IfaceMgr::Iface * tmp = ifacemgr->getIface(5);
     // ASSERT_NE(NULL, tmp); is not supported. hmmmm.
@@ -98,10 +220,10 @@ TEST_F(IfaceMgrTest, getIface) {
     EXPECT_EQ(5, tmp->ifindex_);
 
     // check that interface can be retrieved by name
-    tmp = ifacemgr->getIface("lo");
+    tmp = ifacemgr->getIface("lo1");
     ASSERT_TRUE( tmp != NULL );
 
-    EXPECT_STREQ( "lo", tmp->name_.c_str() );
+    EXPECT_STREQ( "lo1", tmp->name_.c_str() );
     EXPECT_EQ(1, tmp->ifindex_);
 
     // check that non-existing interfaces are not returned
@@ -153,17 +275,22 @@ TEST_F(IfaceMgrTest, DISABLED_sockets) {
     IOAddress loAddr("::1");
 
     // bind multicast socket to port 10547
-    int socket1 = ifacemgr->openSocket("lo", loAddr, 10547);
+    int socket1 = ifacemgr->openSocket(LOOPBACK, loAddr, 10547);
     EXPECT_GT(socket1, 0); // socket > 0
 
     // bind unicast socket to port 10548
-    int socket2 = ifacemgr->openSocket("lo", loAddr, 10548);
+    int socket2 = ifacemgr->openSocket(LOOPBACK, loAddr, 10548);
     EXPECT_GT(socket2, 0);
 
     // expect success. This address/port is already bound, but
     // we are using SO_REUSEADDR, so we can bind it twice
-    int socket3 = ifacemgr->openSocket("lo", loAddr, 10547);
-    EXPECT_GT(socket3, 0); // socket > 0
+    int socket3 = ifacemgr->openSocket(LOOPBACK, loAddr, 10547);
+
+    // rebinding succeeds on Linux, fails on BSD
+    // TODO: add OS-specific defines here (or modify code to
+    // behave the same way on all OSes, but that may not be
+    // possible
+    // EXPECT_GT(socket3, 0); // socket > 0
 
     // we now have 3 sockets open at the same time. Looks good.
 
@@ -186,12 +313,12 @@ TEST_F(IfaceMgrTest, DISABLED_socketsMcast) {
     IOAddress mcastAddr("ff02::1:2");
 
     // bind multicast socket to port 10547
-    int socket1 = ifacemgr->openSocket("lo", mcastAddr, 10547);
+    int socket1 = ifacemgr->openSocket(LOOPBACK, mcastAddr, 10547);
     EXPECT_GT(socket1, 0); // socket > 0
 
     // expect success. This address/port is already bound, but
     // we are using SO_REUSEADDR, so we can bind it twice
-    int socket2 = ifacemgr->openSocket("lo", mcastAddr, 10547);
+    int socket2 = ifacemgr->openSocket(LOOPBACK, mcastAddr, 10547);
     EXPECT_GT(socket2, 0);
 
     // there's no good way to test negative case here.
@@ -214,49 +341,47 @@ TEST_F(IfaceMgrTest, DISABLED_sendReceive) {
     // without interface detection implemented
 
     fstream fakeifaces(INTERFACE_FILE, ios::out|ios::trunc);
-    fakeifaces << "lo ::1";
+    fakeifaces << LOOPBACK << " ::1";
     fakeifaces.close();
 
     NakedIfaceMgr * ifacemgr = new NakedIfaceMgr();
 
     // let's assume that every supported OS have lo interface
     IOAddress loAddr("::1");
-    int socket1 = ifacemgr->openSocket("lo", loAddr, 10547);
-    int socket2 = ifacemgr->openSocket("lo", loAddr, 10546);
+    int socket1 = ifacemgr->openSocket(LOOPBACK, loAddr, 10547);
+    int socket2 = ifacemgr->openSocket(LOOPBACK, loAddr, 10546);
 
     ifacemgr->setSendSock(socket2);
     ifacemgr->setRecvSock(socket1);
 
-    Pkt6 sendPkt(128);
+    boost::shared_ptr<Pkt6> sendPkt(new Pkt6(128) );
 
     // prepare dummy payload
     for (int i=0;i<128; i++) {
-        sendPkt.data_[i] = i;
+        sendPkt->data_[i] = i;
     }
 
-    sendPkt.remote_port_ = 10547;
-    sendPkt.remote_addr_ = IOAddress("::1");
-    sendPkt.ifindex_ = 1;
-    sendPkt.iface_ = "lo";
+    sendPkt->remote_port_ = 10547;
+    sendPkt->remote_addr_ = IOAddress("::1");
+    sendPkt->ifindex_ = 1;
+    sendPkt->iface_ = LOOPBACK;
 
-    Pkt6 * rcvPkt;
+    boost::shared_ptr<Pkt6> rcvPkt;
 
     EXPECT_EQ(true, ifacemgr->send(sendPkt));
 
     rcvPkt = ifacemgr->receive();
 
-    ASSERT_TRUE( rcvPkt != NULL ); // received our own packet
+    ASSERT_TRUE( rcvPkt ); // received our own packet
 
     // let's check that we received what was sent
-    EXPECT_EQ(sendPkt.data_len_, rcvPkt->data_len_);
-    EXPECT_EQ(0, memcmp(&sendPkt.data_[0], &rcvPkt->data_[0],
+    EXPECT_EQ(sendPkt->data_len_, rcvPkt->data_len_);
+    EXPECT_EQ(0, memcmp(&sendPkt->data_[0], &rcvPkt->data_[0],
                         rcvPkt->data_len_) );
 
-    EXPECT_EQ(sendPkt.remote_addr_.toText(), rcvPkt->remote_addr_.toText());
+    EXPECT_EQ(sendPkt->remote_addr_.toText(), rcvPkt->remote_addr_.toText());
     EXPECT_EQ(rcvPkt->remote_port_, 10546);
 
-    delete rcvPkt;
-
     delete ifacemgr;
 }
 
diff --git a/src/bin/dhcp6/tests/pkt6_unittest.cc b/src/bin/dhcp6/tests/pkt6_unittest.cc
deleted file mode 100644
index 5054c45..0000000
--- a/src/bin/dhcp6/tests/pkt6_unittest.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#include <config.h>
-#include <iostream>
-#include <sstream>
-
-#include <arpa/inet.h>
-#include <gtest/gtest.h>
-
-
-#include "dhcp6/pkt6.h"
-
-using namespace std;
-using namespace isc;
-
-namespace {
-// empty class for now, but may be extended once Addr6 becomes bigger
-class Pkt6Test : public ::testing::Test {
-public:
-    Pkt6Test() {
-    }
-};
-
-TEST_F(Pkt6Test, constructor) {
-    Pkt6 * pkt1 = new Pkt6(17);
-    
-    ASSERT_EQ(pkt1->data_len_, 17);
-
-    delete pkt1;
-}
-
-}
diff --git a/src/bin/resolver/tests/Makefile.am b/src/bin/resolver/tests/Makefile.am
index 14d92fe..12ddab3 100644
--- a/src/bin/resolver/tests/Makefile.am
+++ b/src/bin/resolver/tests/Makefile.am
@@ -60,4 +60,4 @@ run_unittests_CXXFLAGS += -Wno-unused-parameter
 endif
 endif
 
-check_PROGRAMS = $(TESTS)
+noinst_PROGRAMS = $(TESTS)
diff --git a/src/bin/sockcreator/tests/Makefile.am b/src/bin/sockcreator/tests/Makefile.am
index b3ca344..223e761 100644
--- a/src/bin/sockcreator/tests/Makefile.am
+++ b/src/bin/sockcreator/tests/Makefile.am
@@ -21,4 +21,4 @@ run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.
 run_unittests_LDADD += $(top_builddir)/src/lib/util/io/libutil_io.la
 endif
 
-check_PROGRAMS = $(TESTS)
+noinst_PROGRAMS = $(TESTS)
diff --git a/src/bin/xfrin/b10-xfrin.8 b/src/bin/xfrin/b10-xfrin.8
index 54dbe7c..056103a 100644
--- a/src/bin/xfrin/b10-xfrin.8
+++ b/src/bin/xfrin/b10-xfrin.8
@@ -2,12 +2,12 @@
 .\"     Title: b10-xfrin
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: September 8, 2011
+.\"      Date: October 12, 2011
 .\"    Manual: BIND10
 .\"    Source: BIND10
 .\"  Language: English
 .\"
-.TH "B10\-XFRIN" "8" "September 8, 2011" "BIND10" "BIND10"
+.TH "B10\-XFRIN" "8" "October 12, 2011" "BIND10" "BIND10"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
@@ -29,23 +29,11 @@ The
 \fBb10\-xfrin\fR
 daemon provides the BIND 10 incoming DNS zone transfer service\&. Normally it is started by the
 \fBbind10\fR(8)
-boss process\&. When triggered it can request and receive a zone transfer and store the zone in a BIND 10 zone data store\&.
-.if n \{\
-.sp
-.\}
-.RS 4
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.ps +1
-\fBNote\fR
-.ps -1
-.br
-.sp
-This prototype release only supports AXFR\&. IXFR is not implemented\&.
-.sp .5v
-.RE
+boss process\&. When triggered it can request and receive a zone transfer and store the zone in a BIND 10 zone data source\&.
+.PP
+The
+\fBb10\-xfrin\fR
+daemon supports both AXFR and IXFR\&. Due to some implementation limitations of the current development release, however, it only tries AXFR by default, and care should be taken to enable IXFR\&. See the BIND 10 Guide for more details\&.
 .PP
 This daemon communicates with BIND 10 over a
 \fBb10-msgq\fR(8)
@@ -77,7 +65,9 @@ daemon\&. The list items are:
 \fImaster_addr\fR
 (the zone master to transfer from),
 \fImaster_port\fR
-(defaults to 53), and
+(defaults to 53),
+\fIuse_ixfr\fR
+(defaults to false), and
 \fItsig_key\fR
 (optional TSIG key to use)\&. The
 \fItsig_key\fR
diff --git a/src/bin/xfrin/b10-xfrin.xml b/src/bin/xfrin/b10-xfrin.xml
index 824d5fa..231681c 100644
--- a/src/bin/xfrin/b10-xfrin.xml
+++ b/src/bin/xfrin/b10-xfrin.xml
@@ -20,7 +20,7 @@
 <refentry>
 
   <refentryinfo>
-    <date>September 8, 2011</date>
+    <date>October 12, 2011</date>
   </refentryinfo>
 
   <refmeta>
@@ -75,6 +75,7 @@ in separate zonemgr process.
       and care should be taken to enable IXFR.
       See the BIND 10 Guide for more details.
     </para>
+<!-- TODO: http://bind10.isc.org/ticket/1279 -->
 
     <para>
       This daemon communicates with BIND 10 over a
@@ -110,7 +111,7 @@ in separate zonemgr process.
       <varname>class</varname> (defaults to <quote>IN</quote>),
       <varname>master_addr</varname> (the zone master to transfer from),
       <varname>master_port</varname> (defaults to 53),
-      <varname>ixfr_disabled</varname> (defaults to false), and
+      <varname>use_ixfr</varname> (defaults to false), and
       <varname>tsig_key</varname> (optional TSIG key to use).
       The <varname>tsig_key</varname> is specified using a full string
       colon-delimited name:key:algorithm representation (e.g.
@@ -158,7 +159,7 @@ in separate zonemgr process.
       according to the SOA's REFRESH time
       to tell <command>b10-xfrin</command> that the zone needs to do
       a zone refresh.
-      This is an internal command and not exposed to the administrator. 
+      This is an internal command and not exposed to the administrator.
 <!-- not defined in spec -->
     </para>
 
@@ -208,7 +209,7 @@ add a usage example of xfrin -->
     </para></note>
 
 <!-- TODO:
- it can handle more than one XFR in now, 
+ it can handle more than one XFR in now,
 but the problem is If SQLITE3 datasource part support multiple write
 operation
 -->
diff --git a/src/bin/xfrin/tests/xfrin_test.py b/src/bin/xfrin/tests/xfrin_test.py
index 5d3a16e..65bd968 100644
--- a/src/bin/xfrin/tests/xfrin_test.py
+++ b/src/bin/xfrin/tests/xfrin_test.py
@@ -98,10 +98,15 @@ class XfrinTestTimeoutException(Exception):
 
 class MockCC():
     def get_default_value(self, identifier):
+        # The returned values should be identical to the spec file
+        # XXX: these should be retrieved from the spec file
+        # (see MyCCSession of xfrout_test.py.in)
         if identifier == "zones/master_port":
             return TEST_MASTER_PORT
         if identifier == "zones/class":
             return TEST_RRCLASS_STR
+        if identifier == "zones/use_ixfr":
+            return False
 
 class MockDataSourceClient():
     '''A simple mock data source client.
@@ -1891,7 +1896,7 @@ class TestXfrin(unittest.TestCase):
         self.assertEqual(self.xfr.command_handler("notify",
                                                   self.args)['result'][0], 1)
 
-    def test_command_handler_notify_known_zone(self):
+    def test_command_handler_notify_known_zone_bad_addr(self):
         # try it with a known zone
         self.args['master'] = TEST_MASTER_IPV6_ADDRESS
 
@@ -1903,18 +1908,39 @@ class TestXfrin(unittest.TestCase):
                   }
                 ]}
         self.xfr.config_handler(zones)
+        # the command should now fail
+        self.assertEqual(self.xfr.command_handler("notify",
+                                                  self.args)['result'][0], 1)
+
+    def test_command_handler_notify_known_zone(self):
+        # try it with a known zone
+        self.args['master'] = TEST_MASTER_IPV6_ADDRESS
+
+        # with a zone configuration that has a matching master address.
+        zones = { 'zones': [
+                  { 'name': TEST_ZONE_NAME_STR,
+                    'master_addr': TEST_MASTER_IPV6_ADDRESS,
+                    'master_port': TEST_MASTER_PORT
+                  }
+                ]}
+        self.xfr.config_handler(zones)
         self.assertEqual(self.xfr.command_handler("notify",
                                                   self.args)['result'][0], 0)
 
+        # Note: The rest of the tests won't pass due to the change in #1298
+        # We should probably simply remove the test cases, but for now we
+        # just comment them out.  (Note also that the comment about 'not
+        # from the config' is now wrong, because we used the matching address.)
+        #
         # and see if we used the address from the command, and not from
         # the config
         # This is actually NOT the address given in the command, which
         # would at this point not make sense, see the TODO in
         # xfrin.py.in Xfrin.command_handler())
-        self.assertEqual(TEST_MASTER_IPV4_ADDRESS,
-                         self.xfr.xfrin_started_master_addr)
-        self.assertEqual(int(TEST_MASTER_PORT),
-                         self.xfr.xfrin_started_master_port)
+#         self.assertEqual(TEST_MASTER_IPV4_ADDRESS,
+#                          self.xfr.xfrin_started_master_addr)
+#         self.assertEqual(int(TEST_MASTER_PORT),
+#                          self.xfr.xfrin_started_master_port)
 
     def test_command_handler_unknown(self):
         self.assertEqual(self.xfr.command_handler("xxx", None)['result'][0], 1)
@@ -1937,20 +1963,24 @@ class TestXfrin(unittest.TestCase):
                 self.assertEqual(zone_info.tsig_key.to_text(), TSIGKey(zone_config['tsig_key']).to_text())
             else:
                 self.assertIsNone(zone_info.tsig_key)
-            if 'ixfr_disabled' in zone_config and\
-               zone_config.get('ixfr_disabled'):
-                self.assertTrue(zone_info.ixfr_disabled)
+            if 'use_ixfr' in zone_config and\
+               zone_config.get('use_ixfr'):
+                self.assertTrue(zone_info.use_ixfr)
             else:
                 # if not set, should default to False
-                self.assertFalse(zone_info.ixfr_disabled)
+                self.assertFalse(zone_info.use_ixfr)
 
-    def test_command_handler_zones(self):
+    def test_config_handler_zones(self):
+        # This test passes a number of good and bad configs, and checks whether
+        # the values are reflected in the structure that will dictate the
+        # actual behaviour. It also checks if bad values are correctly
+        # handled
         config1 = { 'transfers_in': 3,
                    'zones': [
                    { 'name': 'test.example.',
                     'master_addr': '192.0.2.1',
                     'master_port': 53,
-                    'ixfr_disabled': False
+                    'use_ixfr': False
                    }
                  ]}
         self.assertEqual(self.xfr.config_handler(config1)['result'][0], 0)
@@ -1962,7 +1992,7 @@ class TestXfrin(unittest.TestCase):
                     'master_addr': '192.0.2.2',
                     'master_port': 53,
                     'tsig_key': "example.com:SFuWd/q99SzF8Yzd1QbB9g==",
-                    'ixfr_disabled': True
+                    'use_ixfr': True
                    }
                  ]}
         self.assertEqual(self.xfr.config_handler(config2)['result'][0], 0)
@@ -2072,37 +2102,49 @@ class TestXfrin(unittest.TestCase):
         # since this has failed, we should still have the previous config
         self._check_zones_config(config2)
 
-    def common_ixfr_setup(self, xfr_mode, ixfr_disabled):
+    def test_config_handler_zones_default(self):
+        # Checking it some default config values apply.  Using a separate
+        # test case for a fresh xfr object.
+        config = { 'zones': [
+                   { 'name': 'test.example.',
+                    'master_addr': '192.0.2.1',
+                    'master_port': 53,
+                   }
+                 ]}
+        self.assertEqual(self.xfr.config_handler(config)['result'][0], 0)
+        self._check_zones_config(config)
+
+    def common_ixfr_setup(self, xfr_mode, use_ixfr):
         # This helper method explicitly sets up a zone configuration with
-        # ixfr_disabled, and invokes either retransfer or refresh.
+        # use_ixfr, and invokes either retransfer or refresh.
         # Shared by some of the following test cases.
         config = {'zones': [
                 {'name': 'example.com.',
                  'master_addr': '192.0.2.1',
-                 'ixfr_disabled': ixfr_disabled}]}
+                 'use_ixfr': use_ixfr}]}
         self.assertEqual(self.xfr.config_handler(config)['result'][0], 0)
         self.assertEqual(self.xfr.command_handler(xfr_mode,
                                                   self.args)['result'][0], 0)
 
     def test_command_handler_retransfer_ixfr_enabled(self):
         # If IXFR is explicitly enabled in config, IXFR will be used
-        self.common_ixfr_setup('retransfer', False)
+        self.common_ixfr_setup('retransfer', True)
         self.assertEqual(RRType.IXFR(), self.xfr.xfrin_started_request_type)
 
     def test_command_handler_refresh_ixfr_enabled(self):
         # Same for refresh
-        self.common_ixfr_setup('refresh', False)
+        self.common_ixfr_setup('refresh', True)
         self.assertEqual(RRType.IXFR(), self.xfr.xfrin_started_request_type)
 
     def test_command_handler_retransfer_ixfr_disabled(self):
         # Similar to the previous case, but explicitly disabled.  AXFR should
         # be used.
-        self.common_ixfr_setup('retransfer', True)
+        self.common_ixfr_setup('retransfer', False)
         self.assertEqual(RRType.AXFR(), self.xfr.xfrin_started_request_type)
 
     def test_command_handler_refresh_ixfr_disabled(self):
         # Same for refresh
-        self.common_ixfr_setup('refresh', True)
+        self.common_ixfr_setup('refresh', False)
         self.assertEqual(RRType.AXFR(), self.xfr.xfrin_started_request_type)
 
 def raise_interrupt():
diff --git a/src/bin/xfrin/xfrin.py.in b/src/bin/xfrin/xfrin.py.in
index 28d5d50..1f5d9a1 100755
--- a/src/bin/xfrin/xfrin.py.in
+++ b/src/bin/xfrin/xfrin.py.in
@@ -876,7 +876,7 @@ class ZoneInfo:
         self.set_master_port(config_data.get('master_port'))
         self.set_zone_class(config_data.get('class'))
         self.set_tsig_key(config_data.get('tsig_key'))
-        self.set_ixfr_disabled(config_data.get('ixfr_disabled'))
+        self.set_use_ixfr(config_data.get('use_ixfr'))
 
     def set_name(self, name_str):
         """Set the name for this zone given a name string.
@@ -951,15 +951,16 @@ class ZoneInfo:
                 errmsg = "bad TSIG key string: " + tsig_key_str
                 raise XfrinZoneInfoException(errmsg)
 
-    def set_ixfr_disabled(self, ixfr_disabled):
-        """Set ixfr_disabled. If set to False (the default), it will use
-           IXFR for incoming transfers. If set to True, it will use AXFR.
+    def set_use_ixfr(self, use_ixfr):
+        """Set use_ixfr. If set to True, it will use
+           IXFR for incoming transfers. If set to False, it will use AXFR.
            At this moment there is no automatic fallback"""
-        # don't care what type it is; if evaluates to true, set to True
-        if ixfr_disabled:
-            self.ixfr_disabled = True
+        # TODO: http://bind10.isc.org/ticket/1279
+        if use_ixfr is None:
+            self.use_ixfr = \
+                self._module_cc.get_default_value("zones/use_ixfr")
         else:
-            self.ixfr_disabled = False
+            self.use_ixfr = use_ixfr
 
     def get_master_addr_info(self):
         return (self.master_addr.family, socket.SOCK_STREAM,
@@ -1059,20 +1060,33 @@ class Xfrin:
                 # we should check if it matches one of them, and then use it.)
                 (zone_name, rrclass) = self._parse_zone_name_and_class(args)
                 zone_info = self._get_zone_info(zone_name, rrclass)
+                notify_addr = self._parse_master_and_port(args, zone_name,
+                                                          rrclass)
                 if zone_info is None:
                     # TODO what to do? no info known about zone. defaults?
                     errmsg = "Got notification to retransfer unknown zone " + zone_name.to_text()
                     logger.error(XFRIN_RETRANSFER_UNKNOWN_ZONE, zone_name.to_text())
                     answer = create_answer(1, errmsg)
                 else:
+                    request_type = RRType.AXFR()
+                    if zone_info.use_ixfr:
+                        request_type = RRType.IXFR()
                     master_addr = zone_info.get_master_addr_info()
-                    ret = self.xfrin_start(zone_name,
-                                           rrclass,
-                                           self._get_db_file(),
-                                           master_addr,
-                                           zone_info.tsig_key, RRType.AXFR(),
-                                           True)
-                    answer = create_answer(ret[0], ret[1])
+                    if notify_addr == master_addr:
+                        ret = self.xfrin_start(zone_name,
+                                               rrclass,
+                                               self._get_db_file(),
+                                               master_addr,
+                                               zone_info.tsig_key, request_type,
+                                               True)
+                        answer = create_answer(ret[0], ret[1])
+                    else:
+                        errmsg = "Got notification for " + zone_name.to_text()\
+                               + "from unknown address: " + notify_addr[2][0];
+                        logger.error(XFRIN_NOTIFY_UNKNOWN_MASTER,
+                                     zone_name.to_text(), notify_addr[2][0],
+                                     master_addr[2][0])
+                        answer = create_answer(1, errmsg)
 
             elif command == 'retransfer' or command == 'refresh':
                 # Xfrin receives the retransfer/refresh from cmdctl(sent by bindctl).
@@ -1086,7 +1100,7 @@ class Xfrin:
                 request_type = RRType.AXFR()
                 if zone_info:
                     tsig_key = zone_info.tsig_key
-                    if not zone_info.ixfr_disabled:
+                    if zone_info.use_ixfr:
                         request_type = RRType.IXFR()
                 db_file = args.get('db_file') or self._get_db_file()
                 ret = self.xfrin_start(zone_name,
diff --git a/src/bin/xfrin/xfrin.spec b/src/bin/xfrin/xfrin.spec
index bc93720..c1ba61e 100644
--- a/src/bin/xfrin/xfrin.spec
+++ b/src/bin/xfrin/xfrin.spec
@@ -44,7 +44,7 @@
             "item_type": "string",
             "item_optional": true
           },
-          { "item_name": "ixfr_disabled",
+          { "item_name": "use_ixfr",
             "item_type": "boolean",
             "item_optional": false,
             "item_default": false
diff --git a/src/bin/xfrin/xfrin_messages.mes b/src/bin/xfrin/xfrin_messages.mes
index a5bbdf7..e5d1733 100644
--- a/src/bin/xfrin/xfrin_messages.mes
+++ b/src/bin/xfrin/xfrin_messages.mes
@@ -70,6 +70,12 @@ was killed.
 There was a problem sending a message to the zone manager. This most
 likely means that the msgq daemon has quit or was killed.
 
+% XFRIN_NOTIFY_UNKNOWN_MASTER got notification to retransfer zone %1 from %2, expected %3
+The system received a notify for the given zone, but the address it came
+from does not match the master address in the Xfrin configuration. The notify
+is ignored. This may indicate that the configuration for the master is wrong,
+that a wrong machine is sending notifies, or that fake notifies are being sent.
+
 % XFRIN_IMPORT_DNS error importing python DNS module: %1
 There was an error importing the python DNS module pydnspp. The most
 likely cause is a PYTHONPATH problem.
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 04eee45..a569ea7 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -1,3 +1,3 @@
 SUBDIRS = exceptions util log cryptolink dns cc config acl xfr bench \
           asiolink asiodns nsas cache resolve testutils datasrc \
-          server_common python
+          server_common python dhcp
diff --git a/src/lib/acl/tests/Makefile.am b/src/lib/acl/tests/Makefile.am
index 2074c64..6369511 100644
--- a/src/lib/acl/tests/Makefile.am
+++ b/src/lib/acl/tests/Makefile.am
@@ -37,4 +37,4 @@ run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 run_unittests_LDADD += $(top_builddir)/src/lib/acl/libdnsacl.la
 endif
 
-check_PROGRAMS = $(TESTS)
+noinst_PROGRAMS = $(TESTS)
diff --git a/src/lib/asiodns/tests/Makefile.am b/src/lib/asiodns/tests/Makefile.am
index 5a45430..f49d485 100644
--- a/src/lib/asiodns/tests/Makefile.am
+++ b/src/lib/asiodns/tests/Makefile.am
@@ -47,4 +47,4 @@ run_unittests_CXXFLAGS += -Wno-error
 endif
 endif
 
-check_PROGRAMS = $(TESTS)
+noinst_PROGRAMS = $(TESTS)
diff --git a/src/lib/asiolink/io_address.cc b/src/lib/asiolink/io_address.cc
index 7e2f5d4..51c0332 100644
--- a/src/lib/asiolink/io_address.cc
+++ b/src/lib/asiolink/io_address.cc
@@ -23,7 +23,7 @@
 #include <exceptions/exceptions.h>
 #include <asiolink/io_address.h>
 #include <asiolink/io_error.h>
-
+#include <boost/static_assert.hpp>
 
 using namespace asio;
 using asio::ip::udp;
@@ -54,6 +54,22 @@ IOAddress::toText() const {
     return (asio_address_.to_string());
 }
 
+IOAddress
+IOAddress::from_bytes(short family, const uint8_t* data) {
+    if (data == NULL) {
+        isc_throw(BadValue, "NULL pointer received.");
+    } else
+    if ( (family != AF_INET) && (family != AF_INET6) ) {
+        isc_throw(BadValue, "Invalid family type. Only AF_INET and AF_INET6"
+                  << "are supported");
+    }
+
+    BOOST_STATIC_ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
+    char addr_str[INET6_ADDRSTRLEN];
+    inet_ntop(family, data, addr_str, INET6_ADDRSTRLEN);
+    return IOAddress(string(addr_str));
+}
+
 short
 IOAddress::getFamily() const {
     if (asio_address_.is_v4()) {
@@ -63,7 +79,7 @@ IOAddress::getFamily() const {
     }
 }
 
-const asio::ip::address& 
+const asio::ip::address&
 IOAddress::getAddress() const {
     return asio_address_;
 }
diff --git a/src/lib/asiolink/io_address.h b/src/lib/asiolink/io_address.h
index 1b488fa..9fac580 100644
--- a/src/lib/asiolink/io_address.h
+++ b/src/lib/asiolink/io_address.h
@@ -29,6 +29,12 @@
 namespace isc {
 namespace asiolink {
 
+    /// Defines length of IPv6 address.
+    const static size_t V6ADDRESS_LEN = 16;
+
+    /// Defines length of IPv4 address.
+    const static size_t V4ADDRESS_LEN = 4;
+
 /// \brief The \c IOAddress class represents an IP addresses (version
 /// agnostic)
 ///
@@ -87,6 +93,16 @@ public:
     /// \return AF_INET for IPv4 or AF_INET6 for IPv6.
     short getFamily() const;
 
+
+    /// \brief Creates an address from over wire data.
+    ///
+    /// \param family AF_NET for IPv4 or AF_NET6 for IPv6.
+    /// \param data pointer to first char of data
+    ///
+    /// \return Created IOAddress object
+    static IOAddress
+    from_bytes(short family, const uint8_t* data);
+
     /// \brief Compare addresses for equality
     ///
     /// \param other Address to compare against.
diff --git a/src/lib/asiolink/tests/Makefile.am b/src/lib/asiolink/tests/Makefile.am
index 94643c0..984cf07 100644
--- a/src/lib/asiolink/tests/Makefile.am
+++ b/src/lib/asiolink/tests/Makefile.am
@@ -53,4 +53,4 @@ run_unittests_CXXFLAGS += -Wno-error
 endif
 endif
 
-check_PROGRAMS = $(TESTS)
+noinst_PROGRAMS = $(TESTS)
diff --git a/src/lib/asiolink/tests/io_address_unittest.cc b/src/lib/asiolink/tests/io_address_unittest.cc
index 56368a1..eddb0e8 100644
--- a/src/lib/asiolink/tests/io_address_unittest.cc
+++ b/src/lib/asiolink/tests/io_address_unittest.cc
@@ -63,3 +63,23 @@ TEST(IOAddressTest, Family) {
     EXPECT_EQ(AF_INET, IOAddress("192.0.2.1").getFamily());
     EXPECT_EQ(AF_INET6, IOAddress("2001:0DB8:0:0::0012").getFamily());
 }
+
+TEST(IOAddressTest, from_bytes) {
+    // 2001:db8:1::dead:beef
+    uint8_t v6[] = {
+        0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0, 0,
+        0, 0, 0, 0, 0xde, 0xad, 0xbe, 0xef };
+
+    uint8_t v4[] = { 192, 0 , 2, 3 };
+
+    IOAddress addr("::");
+    EXPECT_NO_THROW({
+        addr = IOAddress::from_bytes(AF_INET6, v6);
+    });
+    EXPECT_EQ("2001:db8:1::dead:beef", addr.toText());
+
+    EXPECT_NO_THROW({
+        addr = IOAddress::from_bytes(AF_INET, v4);
+    });
+    EXPECT_EQ(addr.toText(), IOAddress("192.0.2.3").toText());
+}
diff --git a/src/lib/bench/Makefile.am b/src/lib/bench/Makefile.am
index 866404f..514b3b3 100644
--- a/src/lib/bench/Makefile.am
+++ b/src/lib/bench/Makefile.am
@@ -6,6 +6,6 @@ AM_CXXFLAGS = $(B10_CXXFLAGS)
 
 CLEANFILES = *.gcno *.gcda
 
-lib_LTLIBRARIES = libbench.la
+noinst_LTLIBRARIES = libbench.la
 libbench_la_SOURCES = benchmark_util.h benchmark_util.cc
 EXTRA_DIST = benchmark.h
diff --git a/src/lib/bench/tests/Makefile.am b/src/lib/bench/tests/Makefile.am
index 2a6e2c6..3f8a678 100644
--- a/src/lib/bench/tests/Makefile.am
+++ b/src/lib/bench/tests/Makefile.am
@@ -22,6 +22,6 @@ run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 run_unittests_LDADD += $(GTEST_LDADD)
 endif
 
-check_PROGRAMS = $(TESTS)
+noinst_PROGRAMS = $(TESTS)
 
 EXTRA_DIST = testdata/query.txt
diff --git a/src/lib/cache/tests/Makefile.am b/src/lib/cache/tests/Makefile.am
index 0b95036..a215c56 100644
--- a/src/lib/cache/tests/Makefile.am
+++ b/src/lib/cache/tests/Makefile.am
@@ -62,7 +62,7 @@ run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.
 run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 endif
 
-check_PROGRAMS = $(TESTS)
+noinst_PROGRAMS = $(TESTS)
 
 EXTRA_DIST  = testdata/message_cname_referral.wire
 EXTRA_DIST += testdata/message_example_com_soa.wire
diff --git a/src/lib/cc/tests/Makefile.am b/src/lib/cc/tests/Makefile.am
index eebd103..4760855 100644
--- a/src/lib/cc/tests/Makefile.am
+++ b/src/lib/cc/tests/Makefile.am
@@ -32,4 +32,4 @@ run_unittests_LDADD +=  $(top_builddir)/src/lib/exceptions/libexceptions.la
 
 endif
 
-check_PROGRAMS = $(TESTS)
+noinst_PROGRAMS = $(TESTS)
diff --git a/src/lib/config/tests/Makefile.am b/src/lib/config/tests/Makefile.am
index 4fb147d..2f1fc6f 100644
--- a/src/lib/config/tests/Makefile.am
+++ b/src/lib/config/tests/Makefile.am
@@ -11,7 +11,7 @@ endif
 
 CLEANFILES = *.gcno *.gcda
 
-lib_LTLIBRARIES = libfake_session.la
+noinst_LTLIBRARIES = libfake_session.la
 libfake_session_la_SOURCES = fake_session.h fake_session.cc
 
 TESTS =
@@ -31,4 +31,4 @@ run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.
 
 endif
 
-check_PROGRAMS = $(TESTS)
+noinst_PROGRAMS = $(TESTS)
diff --git a/src/lib/cryptolink/tests/Makefile.am b/src/lib/cryptolink/tests/Makefile.am
index 2861edc..fbdd13f 100644
--- a/src/lib/cryptolink/tests/Makefile.am
+++ b/src/lib/cryptolink/tests/Makefile.am
@@ -24,4 +24,4 @@ run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.
 run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 endif
 
-check_PROGRAMS = $(TESTS)
+noinst_PROGRAMS = $(TESTS)
diff --git a/src/lib/datasrc/tests/Makefile.am b/src/lib/datasrc/tests/Makefile.am
index 0be8cd2..3d2ba6d 100644
--- a/src/lib/datasrc/tests/Makefile.am
+++ b/src/lib/datasrc/tests/Makefile.am
@@ -62,7 +62,7 @@ run_unittests_LDADD += $(top_builddir)/src/lib/testutils/libtestutils.la
 run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
 endif
 
-check_PROGRAMS = $(TESTS)
+noinst_PROGRAMS = $(TESTS)
 
 EXTRA_DIST =  testdata/brokendb.sqlite3
 EXTRA_DIST += testdata/example.com.signed
diff --git a/src/lib/dhcp/Makefile.am b/src/lib/dhcp/Makefile.am
new file mode 100644
index 0000000..e146adb
--- /dev/null
+++ b/src/lib/dhcp/Makefile.am
@@ -0,0 +1,25 @@
+SUBDIRS = . tests
+
+AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
+
+AM_CXXFLAGS = $(B10_CXXFLAGS)
+
+CLEANFILES = *.gcno *.gcda
+
+lib_LTLIBRARIES = libdhcp.la
+libdhcp_la_SOURCES  =
+libdhcp_la_SOURCES += libdhcp.cc libdhcp.h
+libdhcp_la_SOURCES += option.cc option.h
+libdhcp_la_SOURCES += option6_ia.cc option6_ia.h
+libdhcp_la_SOURCES += option6_iaaddr.cc option6_iaaddr.h
+libdhcp_la_SOURCES += option6_addrlst.cc option6_addrlst.h
+libdhcp_la_SOURCES += dhcp6.h
+libdhcp_la_SOURCES += pkt6.cc pkt6.h
+
+EXTRA_DIST  = README
+#EXTRA_DIST += log_messages.mes
+
+libdhcp_la_CXXFLAGS = $(AM_CXXFLAGS)
+libdhcp_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
+libdhcp_la_LIBADD   = $(top_builddir)/src/lib/util/libutil.la
diff --git a/src/lib/dhcp/README b/src/lib/dhcp/README
new file mode 100644
index 0000000..6c5353d
--- /dev/null
+++ b/src/lib/dhcp/README
@@ -0,0 +1,11 @@
+This directory holds implementation for libdhcp.
+
+
+Basic Ideas
+===========
+
+
+Notes
+=====
+This work just begun. Don't expect to see much useful code here.
+We are working on it.
\ No newline at end of file
diff --git a/src/lib/dhcp/dhcp6.h b/src/lib/dhcp/dhcp6.h
new file mode 100644
index 0000000..6012003
--- /dev/null
+++ b/src/lib/dhcp/dhcp6.h
@@ -0,0 +1,184 @@
+// Copyright (C) 2006-2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef DHCP6_H
+#define DHCP6_H
+
+/* DHCPv6 Option codes: */
+
+#define D6O_CLIENTID                            1 /* RFC3315 */
+#define D6O_SERVERID                            2
+#define D6O_IA_NA                               3
+#define D6O_IA_TA                               4
+#define D6O_IAADDR                              5
+#define D6O_ORO                                 6
+#define D6O_PREFERENCE                          7
+#define D6O_ELAPSED_TIME                        8
+#define D6O_RELAY_MSG                           9
+/* Option code 10 unassigned. */
+#define D6O_AUTH                                11
+#define D6O_UNICAST                             12
+#define D6O_STATUS_CODE                         13
+#define D6O_RAPID_COMMIT                        14
+#define D6O_USER_CLASS                          15
+#define D6O_VENDOR_CLASS                        16
+#define D6O_VENDOR_OPTS                         17
+#define D6O_INTERFACE_ID                        18
+#define D6O_RECONF_MSG                          19
+#define D6O_RECONF_ACCEPT                       20
+#define D6O_SIP_SERVERS_DNS                     21 /* RFC3319 */
+#define D6O_SIP_SERVERS_ADDR                    22 /* RFC3319 */
+#define D6O_NAME_SERVERS                        23 /* RFC3646 */
+#define D6O_DOMAIN_SEARCH                       24 /* RFC3646 */
+#define D6O_IA_PD                               25 /* RFC3633 */
+#define D6O_IAPREFIX                            26 /* RFC3633 */
+#define D6O_NIS_SERVERS                         27 /* RFC3898 */
+#define D6O_NISP_SERVERS                        28 /* RFC3898 */
+#define D6O_NIS_DOMAIN_NAME                     29 /* RFC3898 */
+#define D6O_NISP_DOMAIN_NAME                    30 /* RFC3898 */
+#define D6O_SNTP_SERVERS                        31 /* RFC4075 */
+#define D6O_INFORMATION_REFRESH_TIME            32 /* RFC4242 */
+#define D6O_BCMCS_SERVER_D                      33 /* RFC4280 */
+#define D6O_BCMCS_SERVER_A                      34 /* RFC4280 */
+/* 35 is unassigned */
+#define D6O_GEOCONF_CIVIC                       36 /* RFC4776 */
+#define D6O_REMOTE_ID                           37 /* RFC4649 */
+#define D6O_SUBSCRIBER_ID                       38 /* RFC4580 */
+#define D6O_CLIENT_FQDN                         39 /* RFC4704 */
+#define D6O_PANA_AGENT                          40 /* paa-option */
+#define D6O_NEW_POSIX_TIMEZONE                  41 /* RFC4833 */
+#define D6O_NEW_TZDB_TIMEZONE                   42 /* RFC4833 */
+#define D6O_ERO                                 43 /* RFC4994 */
+#define D6O_LQ_QUERY                            44 /* RFC5007 */
+#define D6O_CLIENT_DATA                         45 /* RFC5007 */
+#define D6O_CLT_TIME                            46 /* RFC5007 */
+#define D6O_LQ_RELAY_DATA                       47 /* RFC5007 */
+#define D6O_LQ_CLIENT_LINK                      48 /* RFC5007 */
+
+/*
+ * Status Codes, from RFC 3315 section 24.4, and RFC 3633, 5007.
+ */
+#define STATUS_Success           0
+#define STATUS_UnspecFail        1
+#define STATUS_NoAddrsAvail      2
+#define STATUS_NoBinding         3
+#define STATUS_NotOnLink         4
+#define STATUS_UseMulticast      5
+#define STATUS_NoPrefixAvail     6
+#define STATUS_UnknownQueryType  7
+#define STATUS_MalformedQuery    8
+#define STATUS_NotConfigured     9
+#define STATUS_NotAllowed       10
+
+/*
+ * DHCPv6 message types, defined in section 5.3 of RFC 3315
+ */
+#define DHCPV6_SOLICIT              1
+#define DHCPV6_ADVERTISE            2
+#define DHCPV6_REQUEST              3
+#define DHCPV6_CONFIRM              4
+#define DHCPV6_RENEW                5
+#define DHCPV6_REBIND               6
+#define DHCPV6_REPLY                7
+#define DHCPV6_RELEASE              8
+#define DHCPV6_DECLINE              9
+#define DHCPV6_RECONFIGURE         10
+#define DHCPV6_INFORMATION_REQUEST 11
+#define DHCPV6_RELAY_FORW          12
+#define DHCPV6_RELAY_REPL          13
+#define DHCPV6_LEASEQUERY          14
+#define DHCPV6_LEASEQUERY_REPLY    15
+
+extern const char *dhcpv6_type_names[];
+extern const int dhcpv6_type_name_max;
+
+/* DUID type definitions (RFC3315 section 9).
+ */
+#define DUID_LLT        1
+#define DUID_EN         2
+#define DUID_LL         3
+
+/* Offsets into IA_*'s where Option spaces commence.  */
+#define IA_NA_OFFSET 12 /* IAID, T1, T2, all 4 octets each */
+#define IA_TA_OFFSET  4 /* IAID only, 4 octets */
+#define IA_PD_OFFSET 12 /* IAID, T1, T2, all 4 octets each */
+
+/* Offset into IAADDR's where Option spaces commence. */
+#define IAADDR_OFFSET 24
+
+/* Offset into IAPREFIX's where Option spaces commence. */
+#define IAPREFIX_OFFSET 25
+
+/* Offset into LQ_QUERY's where Option spaces commence. */
+#define LQ_QUERY_OFFSET 17
+
+/*
+ * DHCPv6 well-known multicast addressess, from section 5.1 of RFC 3315
+ */
+#define ALL_DHCP_RELAY_AGENTS_AND_SERVERS "ff02::1:2"
+#define ALL_DHCP_SERVERS "ff05::1:3"
+
+#define DHCP6_CLIENT_PORT 546
+#define DHCP6_SERVER_PORT 547
+
+/*
+ * DHCPv6 Retransmission Constants (RFC3315 section 5.5, RFC 5007)
+ */
+
+#define SOL_MAX_DELAY     1
+#define SOL_TIMEOUT       1
+#define SOL_MAX_RT      120
+#define REQ_TIMEOUT       1
+#define REQ_MAX_RT       30
+#define REQ_MAX_RC       10
+#define CNF_MAX_DELAY     1
+#define CNF_TIMEOUT       1
+#define CNF_MAX_RT        4
+#define CNF_MAX_RD       10
+#define REN_TIMEOUT      10
+#define REN_MAX_RT      600
+#define REB_TIMEOUT      10
+#define REB_MAX_RT      600
+#define INF_MAX_DELAY     1
+#define INF_TIMEOUT       1
+#define INF_MAX_RT      120
+#define REL_TIMEOUT       1
+#define REL_MAX_RC        5
+#define DEC_TIMEOUT       1
+#define DEC_MAX_RC        5
+#define REC_TIMEOUT       2
+#define REC_MAX_RC        8
+#define HOP_COUNT_LIMIT  32
+#define LQ6_TIMEOUT       1
+#define LQ6_MAX_RT       10
+#define LQ6_MAX_RC        5
+
+/* Leasequery query-types (RFC 5007) */
+
+#define LQ6QT_BY_ADDRESS        1
+#define LQ6QT_BY_CLIENTID       2
+
+/*
+ * DUID time starts 2000-01-01.
+ * This constant is the number of seconds since 1970-01-01,
+ * when the Unix epoch began.
+ */
+#define DUID_TIME_EPOCH 946684800
+
+/* Information-Request Time option (RFC 4242) */
+
+#define IRT_DEFAULT     86400
+#define IRT_MINIMUM     600
+
+#endif
diff --git a/src/lib/dhcp/libdhcp.cc b/src/lib/dhcp/libdhcp.cc
new file mode 100644
index 0000000..8e6314e
--- /dev/null
+++ b/src/lib/dhcp/libdhcp.cc
@@ -0,0 +1,130 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <boost/shared_array.hpp>
+#include <boost/shared_ptr.hpp>
+#include "dhcp/libdhcp.h"
+#include "config.h"
+#include "dhcp6.h"
+
+#include "option.h"
+#include "option6_ia.h"
+#include "option6_iaaddr.h"
+
+using namespace std;
+using namespace isc::dhcp;
+
+// static array with factories for options
+std::map<unsigned short, Option::Factory*> LibDHCP::v6factories_;
+
+unsigned int
+LibDHCP::unpackOptions6(const boost::shared_array<uint8_t> buf,
+                        unsigned int buf_len,
+                        unsigned int offset, unsigned int parse_len,
+                        isc::dhcp::Option::Option6Collection& options) {
+    if (offset + parse_len > buf_len) {
+        isc_throw(OutOfRange, "Option parse failed. Tried to parse "
+                  << parse_len << " bytes at offset " << offset
+                  << ":  out of buffer");
+    }
+    unsigned int end = offset + parse_len;
+
+    while (offset +4 <= end) {
+        uint16_t opt_type = buf[offset]*256 + buf[offset+1];
+        offset += 2;
+        uint16_t opt_len = buf[offset]*256 + buf[offset+1];
+        offset += 2;
+
+        if (offset + opt_len > end ) {
+            cout << "Option " << opt_type << " truncated." << endl;
+            return (offset);
+        }
+        boost::shared_ptr<Option> opt;
+        switch (opt_type) {
+        case D6O_IA_NA:
+        case D6O_IA_PD:
+            // cout << "Creating Option6IA" << endl;
+            opt = boost::shared_ptr<Option>(new Option6IA(opt_type,
+                                                          buf, buf_len,
+                                                          offset,
+                                                          opt_len));
+            break;
+        case D6O_IAADDR:
+            // cout << "Creating Option6IAAddr" << endl;
+            opt = boost::shared_ptr<Option>(new Option6IAAddr(opt_type,
+                                                              buf, buf_len,
+                                                              offset, opt_len));
+            break;
+        default:
+            // cout << "Creating Option" << endl;
+            opt = boost::shared_ptr<Option>(new Option(Option::V6,
+                                                       opt_type,
+                                                       buf,
+                                                       offset,
+                                                       opt_len));
+            break;
+        }
+        // add option to options
+        options.insert(pair<int, boost::shared_ptr<Option> >(opt_type, opt));
+        offset += opt_len;
+    }
+
+    return (offset);
+}
+
+unsigned int
+LibDHCP::packOptions6(boost::shared_array<uint8_t> data,
+                      unsigned int data_len,
+                      unsigned int offset,
+                      const isc::dhcp::Option::Option6Collection& options) {
+    try {
+        for (isc::dhcp::Option::Option6Collection::const_iterator it = options.begin();
+             it != options.end();
+             ++it) {
+            unsigned short opt_len = (*it).second->len();
+            if (offset + opt_len > data_len) {
+                isc_throw(OutOfRange, "Failed to build option " <<
+                          (*it).first << ": out of buffer");
+            }
+            offset = (*it).second->pack(data, data_len, offset);
+        }
+    }
+    catch (const Exception& e) {
+        cout << "Packet build failed (Option build failed)." << endl;
+        throw;
+    }
+    return (offset);
+}
+
+bool
+LibDHCP::OptionFactoryRegister(Option::Universe u,
+                               unsigned short opt_type,
+                               Option::Factory * factory) {
+    switch (u) {
+    case Option::V6: {
+        if (v6factories_.find(opt_type)!=v6factories_.end()) {
+            isc_throw(BadValue, "There is already DHCPv6 factory registered "
+                     << "for option type "  << opt_type);
+        }
+        v6factories_[opt_type]=factory;
+        return true;
+    }
+    case Option::V4:
+    default:{
+        isc_throw(BadValue, "This universe type is not supported yet.");
+        return false; // never happens
+    }
+    }
+
+}
diff --git a/src/lib/dhcp/libdhcp.h b/src/lib/dhcp/libdhcp.h
new file mode 100644
index 0000000..c2ac949
--- /dev/null
+++ b/src/lib/dhcp/libdhcp.h
@@ -0,0 +1,83 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef LIBDHCP_H_
+#define LIBDHCP_H_
+
+#include <iostream>
+#include "dhcp/pkt6.h"
+
+namespace isc {
+namespace dhcp {
+
+class LibDHCP {
+
+public:
+    /// Builds collection of options.
+    ///
+    /// Builds raw (on-wire) data for provided collection of options.
+    ///
+    /// @param buf shared pointer to buffer. Data will be stored there.
+    /// @param buf_len buffer length. Used for buffer overflow protection.
+    /// @param offset Offset from beginning of the buffer, where store options
+    /// @param options collection of options to store to
+    ///
+    /// @return offset to the first unused byte in buffer (next one after last
+    ///         used byte)
+    ///
+    static unsigned int
+    packOptions6(boost::shared_array<uint8_t> buf, unsigned int buf_len,
+                 unsigned int offset,
+                 const isc::dhcp::Option::Option6Collection& options);
+
+    ///
+    /// Parses provided buffer and creates Option objects.
+    ///
+    /// Parses provided buf array and stores created Option objects
+    /// in options container.
+    ///
+    /// @param buf Buffer to be parsed.
+    /// @param offset Specifies offset for the first option.
+    /// @param options Reference to option container. Options will be
+    ///        put here.
+    ///
+    /// @return offset to first byte after last parsed option
+    ///
+    static unsigned int
+    unpackOptions6(const boost::shared_array<uint8_t> buf, unsigned int buf_len,
+                   unsigned int offset, unsigned int parse_len,
+                   isc::dhcp::Option::Option6Collection& options_);
+
+    ///
+    /// Registers factory method that produces options of specific option types.
+    ///
+    /// @param u universe of the option (V4 or V6)
+    /// @param opt_type option-type
+    /// @param factory function pointer
+    ///
+    /// @return true, if registration was successful, false otherwise
+    ///
+    static bool
+    OptionFactoryRegister(Option::Universe u,
+                          unsigned short type,
+                          Option::Factory * factory);
+protected:
+    // pointers to factories that produce DHCPv6 options
+    static std::map<unsigned short, Option::Factory*> v6factories_;
+};
+
+}
+}
+
+#endif
diff --git a/src/lib/dhcp/option.cc b/src/lib/dhcp/option.cc
new file mode 100644
index 0000000..1ff2c85
--- /dev/null
+++ b/src/lib/dhcp/option.cc
@@ -0,0 +1,262 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <string.h>
+#include <stdint.h>
+#include <arpa/inet.h>
+#include <sstream>
+#include <iomanip>
+#include <boost/shared_array.hpp>
+#include "exceptions/exceptions.h"
+#include "util/io_utilities.h"
+
+#include "dhcp/option.h"
+#include "dhcp/libdhcp.h"
+
+using namespace std;
+using namespace isc::dhcp;
+using namespace isc::util;
+
+Option::Option(Universe u, unsigned short type)
+    :universe_(u), type_(type), data_len_(0) {
+
+
+}
+
+Option::Option(Universe u, unsigned short type,
+               const boost::shared_array<uint8_t>& buf,
+               unsigned int offset, unsigned int len)
+    :universe_(u), type_(type), data_(buf),
+     data_len_(len), offset_(offset)
+      {
+
+    // sanity checks
+    // TODO: universe must be in V4 and V6
+}
+
+unsigned int
+Option::pack(boost::shared_array<uint8_t>& buf,
+             unsigned int buf_len,
+             unsigned int offset) {
+    switch (universe_) {
+    case V4:
+        return pack4(buf, buf_len, offset);
+    case V6:
+        return pack6(buf, buf_len, offset);
+    default:
+        isc_throw(BadValue, "Unknown universe defined for Option " << type_);
+    }
+}
+
+
+unsigned int
+Option::pack4(boost::shared_array<uint8_t>& buf,
+             unsigned int buf_len,
+             unsigned int offset) {
+    if ( offset+len() > buf_len ) {
+        isc_throw(OutOfRange, "Failed to pack v4 option=" <<
+                  type_ << ",len=" << data_len_ << ": too small buffer.");
+    }
+    uint8_t *ptr = &buf[offset];
+    ptr[0] = type_;
+    ptr[1] = data_len_;
+    ptr += 2;
+    memcpy(ptr, &data_[0], data_len_);
+
+    return offset + len();
+}
+
+unsigned int
+Option::pack6(boost::shared_array<uint8_t>& buf,
+             unsigned int buf_len,
+             unsigned int offset) {
+    if ( offset+len() > buf_len ) {
+        isc_throw(OutOfRange, "Failed to pack v6 option=" <<
+                  type_ << ",len=" << len() << ": too small buffer.");
+    }
+
+    int length = len() - getHeaderLen();
+
+    uint8_t * ptr = &buf[offset];
+    writeUint16(type_, ptr);
+    ptr += sizeof(uint16_t);
+
+    writeUint16(length, ptr);
+    ptr += sizeof(uint16_t);
+
+    if (data_len_)
+        memcpy(ptr, &data_[offset_], data_len_);
+
+    offset += OPTION6_HDR_LEN + data_len_; // end of this option
+
+    return LibDHCP::packOptions6(buf, buf_len, offset, options_);
+}
+
+unsigned int
+Option::unpack(const boost::shared_array<uint8_t>& buf,
+               unsigned int buf_len,
+               unsigned int offset,
+               unsigned int parse_len) {
+    switch (universe_) {
+    case V4:
+        return unpack4(buf, buf_len, offset, parse_len);
+    case V6:
+        return unpack6(buf, buf_len, offset, parse_len);
+    default:
+        isc_throw(BadValue, "Unknown universe defined for Option " << type_);
+    }
+
+    return 0; // should not happen
+}
+
+unsigned int
+Option::unpack4(const boost::shared_array<uint8_t>&,
+                unsigned int ,
+                unsigned int ,
+                unsigned int ) {
+    isc_throw(Unexpected, "IPv4 support not implemented yet.");
+    return 0;
+}
+
+unsigned int
+Option::unpack6(const boost::shared_array<uint8_t>& buf,
+                unsigned int buf_len,
+                unsigned int offset,
+                unsigned int parse_len) {
+
+    if (buf_len < offset+parse_len) {
+        isc_throw(OutOfRange, "Failed to unpack DHCPv6 option len="
+                  << parse_len << " offset=" << offset
+                  << " from buffer (length=" << buf_len
+                  << "): too small buffer.");
+    }
+
+    data_ = buf;
+    offset_ = offset;
+    data_len_ = buf_len;
+
+    return LibDHCP::unpackOptions6(buf, buf_len, offset, parse_len,
+                                   options_);
+}
+
+unsigned short
+Option::len() {
+
+    // length of the whole option is header and data stored in this option...
+    int length = getHeaderLen() + data_len_;
+
+    // ... and sum of lengths of all suboptions
+    for (Option::Option6Collection::iterator it = options_.begin();
+         it != options_.end();
+         ++it) {
+        length += (*it).second->len();
+    }
+
+    // note that this is not equal to lenght field. This value denotes
+    // number of bytes required to store this option. length option should
+    // contain (len()-getHeaderLen()) value.
+    return (length);
+}
+
+bool
+Option::valid() {
+    if (universe_ != V4 &&
+        universe_ != V6) {
+        return (false);
+    }
+
+    return (true);
+}
+
+void
+isc::dhcp::Option::addOption(boost::shared_ptr<isc::dhcp::Option> opt) {
+    options_.insert(pair<int, boost::shared_ptr<Option> >(opt->getType(),
+                                                            opt));
+
+}
+
+boost::shared_ptr<isc::dhcp::Option>
+Option::getOption(unsigned short opt_type) {
+    isc::dhcp::Option::Option6Collection::const_iterator x =
+        options_.find(opt_type);
+    if ( x != options_.end() ) {
+        return (*x).second;
+    }
+    return boost::shared_ptr<isc::dhcp::Option>(); // NULL
+}
+
+bool
+Option::delOption(unsigned short opt_type) {
+    isc::dhcp::Option::Option6Collection::iterator x = options_.find(opt_type);
+    if ( x != options_.end() ) {
+        options_.erase(x);
+        return true; // delete successful
+    }
+    return (false); // option not found, can't delete
+}
+
+
+std::string Option::toText(int indent /* =0 */ ) {
+    std::stringstream tmp;
+
+    for (int i=0; i<indent; i++)
+        tmp << " ";
+
+    tmp << "type=" << type_ << ", len=" << data_len_ << ": ";
+
+    for (unsigned int i=0; i<data_len_; i++) {
+        if (i) {
+            tmp << ":";
+        }
+        tmp << setfill('0') << setw(2) << hex
+            << static_cast<unsigned short>(data_[offset_+i]);
+    }
+
+    // print suboptions
+    for (Option6Collection::const_iterator opt=options_.begin();
+         opt!=options_.end();
+         ++opt) {
+        tmp << (*opt).second->toText(indent+2);
+    }
+    return tmp.str();
+}
+
+unsigned short
+Option::getType() {
+    return type_;
+}
+
+uint8_t*
+Option::getData() {
+    if (data_len_) {
+        return (&data_[offset_]);
+    } else {
+        return (NULL);
+    }
+}
+
+unsigned short
+Option::getHeaderLen() {
+    switch (universe_) {
+    case V4:
+        return OPTION4_HDR_LEN; // header length for v4
+    case V6:
+        return OPTION6_HDR_LEN; // header length for v6
+    }
+    return 0; // should not happen
+}
+
+Option::~Option() {
+
+}
diff --git a/src/lib/dhcp/option.h b/src/lib/dhcp/option.h
new file mode 100644
index 0000000..5be1be3
--- /dev/null
+++ b/src/lib/dhcp/option.h
@@ -0,0 +1,273 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef OPTION_H_
+#define OPTION_H_
+
+#include <string>
+#include <map>
+#include <boost/shared_ptr.hpp>
+#include <boost/shared_array.hpp>
+
+namespace isc {
+namespace dhcp {
+
+class Option {
+public:
+    /// length of the usual DHCPv4 option header (there are exceptions)
+    const static size_t OPTION4_HDR_LEN = 2;
+
+    /// length of any DHCPv6 option header
+    const static size_t OPTION6_HDR_LEN = 4;
+
+    /// defines option universe DHCPv4 or DHCPv6
+    enum Universe { V4, V6 };
+
+    /// a collection of DHCPv4 options
+    typedef std::map<unsigned int, boost::shared_ptr<Option> >
+    Option4Collection;
+
+    /// a collection of DHCPv6 options
+    typedef std::multimap<unsigned int, boost::shared_ptr<Option> >
+    Option6Collection;
+
+    /// @brief a factory function prototype
+    ///
+    /// @param u option universe (DHCPv4 or DHCPv6)
+    /// @param type option type
+    /// @param buf pointer to a buffer
+    /// @param offset offset to first data byte in that buffer
+    /// @param len data length of this option
+    ///
+    /// @return a pointer to a created option object
+    typedef boost::shared_ptr<Option> Factory(Option::Universe u,
+                                              unsigned short type,
+                                              boost::shared_array<uint8_t>& buf,
+                                              unsigned int offset,
+                                              unsigned int len);
+
+    /// @brief ctor, used for options constructed, usually during transmission
+    ///
+    /// @param u option universe (DHCPv4 or DHCPv6)
+    /// @param type option type
+    Option(Universe u, unsigned short type);
+
+    /// @brief ctor, used for received options
+    ///
+    /// boost::shared_array allows sharing a buffer, but it requires that
+    /// different instances share pointer to the whole array, not point
+    /// to different elements in shared array. Therefore we need to share
+    /// pointer to the whole array and remember offset where data for
+    /// this option begins
+    ///
+    /// @param u specifies universe (V4 or V6)
+    /// @param type option type
+    /// @param buf pointer to a buffer
+    /// @param offset offset in a buffer pointing to first byte of data
+    /// @param len length of the option data
+    Option(Universe u, unsigned short type,
+           const boost::shared_array<uint8_t>& buf, unsigned int offset,
+           unsigned int len);
+
+    /// @brief writes option in wire-format to buf
+    ///
+    /// Writes option in wire-format to buffer, returns pointer to first unused
+    /// byte after stored option (that is useful for writing options one after
+    /// another)
+    ///
+    /// @param buf pointer to a buffer
+    /// @param buf_len length of the buffer
+    /// @param offset offset to place, where option shout be stored
+    ///
+    /// @return offset to first unused byte after stored option
+    ///
+    virtual unsigned int
+    pack(boost::shared_array<uint8_t>& buf,
+         unsigned int buf_len,
+         unsigned int offset);
+
+    /// @brief Parses buffer.
+    ///
+    /// Parses received buffer, returns offset to the first unused byte after
+    /// parsed option.
+    ///
+    /// @param buf pointer to buffer
+    /// @param buf_len length of buf
+    /// @param offset offset, where start parsing option
+    /// @param parse_len how many bytes should be parsed
+    ///
+    /// @return offset after last parsed octet
+    virtual unsigned int
+    unpack(const boost::shared_array<uint8_t>& buf,
+           unsigned int buf_len,
+           unsigned int offset,
+           unsigned int parse_len);
+
+    /// Returns string representation of the option.
+    ///
+    /// @param indent number of spaces before printing text
+    ///
+    /// @return string with text representation.
+    virtual std::string
+    toText(int indent = 0);
+
+    /// Returns option type (0-255 for DHCPv4, 0-65535 for DHCPv6)
+    ///
+    /// @return option type
+    unsigned short
+    getType();
+
+    /// Returns length of the complete option (data length + DHCPv4/DHCPv6
+    /// option header)
+    ///
+    /// @return length of the option
+    virtual unsigned short
+    len();
+
+    /// @brief Returns length of header (2 for v4, 4 for v6)
+    ///
+    /// @return length of option header
+    virtual unsigned short
+    getHeaderLen();
+
+    /// returns if option is valid (e.g. option may be truncated)
+    ///
+    /// @return true, if option is valid
+    virtual bool
+    valid();
+
+    /// Returns pointer to actual data.
+    ///
+    /// @return pointer to actual data (or NULL if there is no data)
+    virtual uint8_t*
+    getData();
+
+    /// Adds a sub-option.
+    ///
+    /// Some DHCPv6 options can have suboptions. This method allows adding
+    /// options within options.
+    ///
+    /// Note: option is passed by value. That is very convenient as it allows
+    /// downcasting from any derived classes, e.g. shared_ptr<Option6_IA> type
+    /// can be passed directly, without any casts. That would not be possible
+    /// with passing by reference. addOption() is expected to be used in
+    /// many places. Requiring casting is not feasible.
+    ///
+    /// @param opt shared pointer to a suboption that is going to be added.
+    void
+    addOption(boost::shared_ptr<Option> opt);
+
+    /// Returns shared_ptr to suboption of specific type
+    ///
+    /// @param type type of requested suboption
+    ///
+    /// @return shared_ptr to requested suoption
+    boost::shared_ptr<isc::dhcp::Option>
+    getOption(unsigned short type);
+
+    /// Attempts to delete first suboption of requested type
+    ///
+    /// @param type Type of option to be deleted.
+    ///
+    /// @return true if option was deleted, false if no such option existed
+    bool
+    delOption(unsigned short type);
+
+    /// just to force that every option has virtual dtor
+    virtual
+    ~Option();
+
+protected:
+
+    /// Builds raw (over-wire) buffer of this option, including all
+    /// defined suboptions. Version for building DHCPv4 options.
+    ///
+    /// @param buf output buffer (built options will be stored here)
+    /// @param buf_len buffer length (used for buffer overflow checks)
+    /// @param offset offset from start of the buf buffer
+    ///
+    /// @return offset to the next byte after last used byte
+    virtual unsigned int
+    pack4(boost::shared_array<uint8_t>& buf,
+          unsigned int buf_len,
+          unsigned int offset);
+
+    /// Builds raw (over-wire) buffer of this option, including all
+    /// defined suboptions. Version for building DHCPv4 options.
+    ///
+    /// @param buf output buffer (built options will be stored here)
+    /// @param buf_len buffer length (used for buffer overflow checks)
+    /// @param offset offset from start of the buf buffer
+    ///
+    /// @return offset to the next byte after last used byte
+    virtual unsigned int
+    pack6(boost::shared_array<uint8_t>& buf,
+          unsigned int buf_len,
+          unsigned int offset);
+
+    /// Parses provided buffer and creates DHCPv4 options.
+    ///
+    /// @param buf buffer that contains raw buffer to parse (on-wire format)
+    /// @param buf_len buffer length (used for buffer overflow checks)
+    /// @param offset offset from start of the buf buffer
+    ///
+    /// @return offset to the next byte after last parsed byte
+    virtual unsigned int
+    unpack4(const boost::shared_array<uint8_t>& buf,
+            unsigned int buf_len,
+            unsigned int offset,
+            unsigned int parse_len);
+
+    /// Parses provided buffer and creates DHCPv6 options.
+    ///
+    /// @param buf buffer that contains raw buffer to parse (on-wire format)
+    /// @param buf_len buffer length (used for buffer overflow checks)
+    /// @param offset offset from start of the buf buffer
+    ///
+    /// @return offset to the next byte after last parsed byte
+    virtual unsigned int
+    unpack6(const boost::shared_array<uint8_t>& buf,
+            unsigned int buf_len,
+            unsigned int offset,
+            unsigned int parse_len);
+
+    /// option universe (V4 or V6)
+    Universe universe_;
+
+    /// option type (0-255 for DHCPv4, 0-65535 for DHCPv6)
+    unsigned short type_;
+
+    /// shared pointer to a buffer (usually a part of packet)
+    boost::shared_array<uint8_t> data_;
+
+    /// length of data only. Use len() if you want to
+    /// know proper length with option header overhead
+    unsigned int data_len_;
+
+    /// data is a shared_pointer that points out to the
+    /// whole packet. offset_ specifies where data for
+    /// this option begins.
+    unsigned int offset_;
+
+    /// collection for storing suboptions
+    Option6Collection options_;
+
+    /// TODO: probably 2 different containers have to be used for v4 (unique
+    /// options) and v6 (options with the same type can repeat)
+};
+
+} // namespace isc::dhcp
+} // namespace isc
+
+#endif
diff --git a/src/lib/dhcp/option6_addrlst.cc b/src/lib/dhcp/option6_addrlst.cc
new file mode 100644
index 0000000..fc981fa
--- /dev/null
+++ b/src/lib/dhcp/option6_addrlst.cc
@@ -0,0 +1,134 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <stdint.h>
+#include <arpa/inet.h>
+#include <sstream>
+#include "exceptions/exceptions.h"
+
+#include "asiolink/io_address.h"
+#include "util/io_utilities.h"
+#include "dhcp/libdhcp.h"
+#include "dhcp/option6_addrlst.h"
+#include "dhcp/dhcp6.h"
+
+using namespace std;
+using namespace isc;
+using namespace isc::dhcp;
+using namespace isc::asiolink;
+using namespace isc::util;
+
+Option6AddrLst::Option6AddrLst(unsigned short type,
+                               const AddressContainer& addrs)
+    :Option(V6, type), addrs_(addrs) {
+}
+
+Option6AddrLst::Option6AddrLst(unsigned short type,
+                               const isc::asiolink::IOAddress& addr)
+    :Option(V6, type), addrs_(1,addr) {
+}
+
+Option6AddrLst::Option6AddrLst(unsigned short type,
+                               boost::shared_array<uint8_t> buf,
+                               unsigned int buf_len,
+                               unsigned int offset,
+                               unsigned int option_len)
+    :Option(V6, type) {
+    unpack(buf, buf_len, offset, option_len);
+}
+
+void
+Option6AddrLst::setAddress(const isc::asiolink::IOAddress& addr) {
+    addrs_.clear();
+    addrs_.push_back(addr);
+}
+
+void
+Option6AddrLst::setAddresses(const AddressContainer& addrs) {
+    addrs_ = addrs;
+}
+
+unsigned int
+Option6AddrLst::pack(boost::shared_array<uint8_t>& buf,
+                    unsigned int buf_len,
+                    unsigned int offset) {
+    if (len() > buf_len) {
+        isc_throw(OutOfRange, "Failed to pack IA option: len=" << len()
+                  << ", buffer=" << buf_len << ": too small buffer.");
+    }
+
+    writeUint16(type_, &buf[offset]);
+    offset += sizeof(uint16_t);
+
+    // len() returns complete option length.
+    // len field contains length without 4-byte option header
+    writeUint16(len() - OPTION6_HDR_LEN, &buf[offset]);
+    offset += sizeof(uint16_t);
+
+    // this wrapping is *ugly*. I wish there was a a
+    for (AddressContainer::const_iterator addr=addrs_.begin();
+         addr!=addrs_.end();
+         ++addr) {
+        memcpy(&buf[offset],
+               addr->getAddress().to_v6().to_bytes().data(),
+               V6ADDRESS_LEN);
+        offset += V6ADDRESS_LEN;
+    }
+
+    return offset;
+}
+
+unsigned int
+Option6AddrLst::unpack(const boost::shared_array<uint8_t>& buf,
+                       unsigned int buf_len,
+                       unsigned int offset,
+                       unsigned int option_len) {
+    if (offset+option_len > buf_len) {
+        isc_throw(OutOfRange, "Option " << type_
+                  << " truncated.");
+    }
+
+    if (option_len%16) {
+        isc_throw(OutOfRange, "Option " << type_
+                  << " malformed: len=" << option_len
+                  << " is not divisible by 16.");
+    }
+    while (option_len > 0) {
+        addrs_.push_back(IOAddress::from_bytes(AF_INET6, &buf[offset]));
+        offset += 16;
+        option_len -= 16;
+    }
+
+    return offset;
+}
+
+std::string Option6AddrLst::toText(int indent /* =0 */) {
+    stringstream tmp;
+    for (int i=0; i<indent; i++)
+        tmp << " ";
+
+    tmp << "type=" << type_ << " " << addrs_.size() << "addr(s): ";
+
+    for (AddressContainer::const_iterator addr=addrs_.begin();
+         addr!=addrs_.end();
+         ++addr) {
+        tmp << addr->toText() << " ";
+    }
+    return tmp.str();
+}
+
+unsigned short Option6AddrLst::len() {
+
+    return (OPTION6_HDR_LEN + addrs_.size()*16);
+}
diff --git a/src/lib/dhcp/option6_addrlst.h b/src/lib/dhcp/option6_addrlst.h
new file mode 100644
index 0000000..c5b32af
--- /dev/null
+++ b/src/lib/dhcp/option6_addrlst.h
@@ -0,0 +1,127 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef OPTION6_ADDRLST_H_
+#define OPTION6_ADDRLST_H_
+
+#include <vector>
+#include "asiolink/io_address.h"
+#include "dhcp/option.h"
+
+namespace isc {
+namespace dhcp {
+
+/// @brief Option class for handling list of IPv6 addresses.
+///
+/// This class handles a list of IPv6 addresses. An example of such option
+/// is dns-servers option. It can also be used to handle single address.
+///
+class Option6AddrLst: public Option {
+
+public:
+    /// a container for (IPv6) addresses
+    typedef std::vector<isc::asiolink::IOAddress> AddressContainer;
+
+    /// @brief Constructor used during option generation.
+    ///
+    /// @param type option type
+    /// @param addrs vector of addresses to be stored
+    ///
+    Option6AddrLst(unsigned short type,
+                   const AddressContainer& addrs);
+
+    /// @brief Simplified constructor for a single address
+    ///
+    /// @param type option type
+    /// @param addr a single address to be stored
+    ///
+    Option6AddrLst(unsigned short type,
+                   const isc::asiolink::IOAddress& addr);
+
+    /// @brief Constructor used for parsing received option
+    ///
+    /// @param type option type
+    /// @param buf pointer to packet buffer
+    /// @param buf_len length of packet buffer
+    /// @param offset offset to beginning of option data
+    /// @param len length of option data
+    ///
+    Option6AddrLst(unsigned short type, boost::shared_array<uint8_t> buf,
+                   unsigned int buf_len,
+                   unsigned int offset,
+                   unsigned int len);
+
+    /// @brief Assembles on-wire form of this option
+    ///
+    /// @param buf pointer to packet buffer
+    /// @param buf_len length of packet buffer
+    /// @param offset offset to place, where option is to be stored
+    ///
+    /// @return offset to the next unused char (just after stored option)
+    ///
+    unsigned int
+    pack(boost::shared_array<uint8_t>& buf, unsigned int buf_len,
+         unsigned int offset);
+
+    /// @brief Parses received data
+    ///
+    /// @param buf pointer to packet buffer
+    /// @param buf_len length of packet buffer
+    /// @param offset offset to option data
+    /// @param parse_len specified option data length
+    ///
+    /// @return offset to the next unparsed char (just after parsed option)
+    ///
+    virtual unsigned int
+    unpack(const boost::shared_array<uint8_t>& buf,
+           unsigned int buf_len,
+           unsigned int offset,
+           unsigned int parse_len);
+
+    virtual std::string toText(int indent = 0);
+
+    /// @brief Sets a single address.
+    ///
+    /// @param addr a single address to be added
+    ///
+    void setAddress(const isc::asiolink::IOAddress& addr);
+
+    /// @brief Sets list of addresses.
+    ///
+    /// @param addrs a vector of addresses to be added
+    ///
+    void setAddresses(const AddressContainer& addrs);
+
+    /// @brief Returns vector with addresses.
+    ///
+    /// As user may want to use/modify this list, it is better to return
+    /// a copy rather than const reference to the original. This is
+    /// usually one or two addresses long, so it is not a big deal.
+    ///
+    /// @return vector with addresses
+    ///
+    AddressContainer
+    getAddresses() { return addrs_; };
+
+    // returns data length (data length + DHCPv4/DHCPv6 option header)
+    virtual unsigned short len();
+
+protected:
+    AddressContainer addrs_;
+};
+
+} // isc::dhcp namespace
+} // isc namespace
+
+#endif /* OPTION_ADDRLST_H_ */
diff --git a/src/lib/dhcp/option6_ia.cc b/src/lib/dhcp/option6_ia.cc
new file mode 100644
index 0000000..350b32e
--- /dev/null
+++ b/src/lib/dhcp/option6_ia.cc
@@ -0,0 +1,139 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <stdint.h>
+#include <arpa/inet.h>
+#include <sstream>
+#include "exceptions/exceptions.h"
+
+#include "dhcp/libdhcp.h"
+#include "dhcp/option6_ia.h"
+#include "dhcp/dhcp6.h"
+#include "util/io_utilities.h"
+
+using namespace std;
+using namespace isc;
+using namespace isc::dhcp;
+using namespace isc::util;
+
+Option6IA::Option6IA(unsigned short type, unsigned int iaid)
+    :Option(Option::V6, type), iaid_(iaid) {
+}
+
+Option6IA::Option6IA(unsigned short type,
+                     const boost::shared_array<uint8_t>& buf,
+                     unsigned int buf_len,
+                     unsigned int offset,
+                     unsigned int option_len)
+    :Option(Option::V6, type) {
+    unpack(buf, buf_len, offset, option_len);
+}
+
+unsigned int
+Option6IA::pack(boost::shared_array<uint8_t>& buf,
+                unsigned int buf_len,
+                unsigned int offset) {
+    if (offset + len() > buf_len) {
+        isc_throw(OutOfRange, "Failed to pack IA option: len=" << len()
+                  << ", buffer=" << buf_len << ": too small buffer.");
+    }
+
+    if (len() < 16 ) {
+        isc_throw(OutOfRange, "Attempt to build malformed IA option: len="
+                  << len() << " is too small (at least 16 is required).");
+    }
+
+    writeUint16(type_, &buf[offset]);
+    offset += sizeof(uint16_t);
+
+    writeUint16(len() - OPTION6_HDR_LEN, &buf[offset]);
+    offset += sizeof(uint16_t);
+
+    /// TODO start using writeUint32 once such function is implemented
+    uint8_t* ptr = &buf[offset];
+
+    *(uint32_t*)ptr = htonl(iaid_);
+    ptr += sizeof(uint32_t);
+
+    *(uint32_t*)ptr = htonl(t1_);
+    ptr += sizeof(uint32_t);
+
+    *(uint32_t*)ptr = htonl(t2_);
+    ptr += sizeof(uint32_t);
+
+    offset = LibDHCP::packOptions6(buf, buf_len, offset+12, options_);
+    return offset;
+}
+
+unsigned int
+Option6IA::unpack(const boost::shared_array<uint8_t>& buf,
+                  unsigned int buf_len,
+                  unsigned int offset,
+                  unsigned int parse_len) {
+    if ( parse_len < OPTION6_IA_LEN || offset + OPTION6_IA_LEN > buf_len) {
+        isc_throw(OutOfRange, "Option " << type_ << " truncated");
+    }
+    iaid_ = ntohl(*(uint32_t*)&buf[offset]);
+    offset += sizeof(uint32_t);
+    t1_ = ntohl(*(uint32_t*)&buf[offset]);
+    offset += sizeof(uint32_t);
+    t2_ = ntohl(*(uint32_t*)&buf[offset]);
+    offset += sizeof(uint32_t);
+    offset = LibDHCP::unpackOptions6(buf, buf_len, offset,
+                                     parse_len - OPTION6_IA_LEN, options_);
+
+    return (offset);
+}
+
+std::string Option6IA::toText(int indent /* = 0*/) {
+    stringstream tmp;
+
+    for (int i=0; i<indent; i++)
+        tmp << " ";
+    tmp << "type=" << type_;
+
+    switch (type_) {
+    case D6O_IA_NA:
+        tmp << "(IA_NA)";
+        break;
+    case D6O_IA_PD:
+        tmp << "(IA_PD)";
+        break;
+    default:
+        tmp << "(unknown)";
+    }
+    tmp << " iaid=" << iaid_ << ", t1=" << t1_ << ", t2=" << t2_
+        << " " << options_.size() << " sub-options:" << endl;
+
+    for (Option6Collection::const_iterator opt=options_.begin();
+         opt!=options_.end();
+         ++opt) {
+        tmp << (*opt).second->toText(indent+2);
+    }
+    return tmp.str();
+}
+
+unsigned short Option6IA::len() {
+
+    unsigned short length = OPTION6_HDR_LEN /*header (4)*/ +
+        OPTION6_IA_LEN  /* option content (12) */;
+
+    // length of all suboptions
+    for (Option::Option6Collection::iterator it = options_.begin();
+         it != options_.end();
+         ++it) {
+        length += (*it).second->len();
+    }
+    return (length);
+}
diff --git a/src/lib/dhcp/option6_ia.h b/src/lib/dhcp/option6_ia.h
new file mode 100644
index 0000000..516b2fc
--- /dev/null
+++ b/src/lib/dhcp/option6_ia.h
@@ -0,0 +1,137 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef OPTION_IA_H_
+#define OPTION_IA_H_
+
+#include <stdint.h>
+#include "option.h"
+
+namespace isc {
+namespace dhcp {
+
+class Option6IA: public Option {
+
+public:
+    /// Length of IA_NA and IA_PD content
+    const static size_t OPTION6_IA_LEN = 12;
+
+    /// @brief ctor, used for options constructed, usually during transmission
+    ///
+    /// @param type option type (usually 4 for IA_NA, 25 for IA_PD)
+    /// @param iaid identity association identifier (id of IA)
+    Option6IA(uint16_t type, unsigned int iaid);
+
+    /// @brief ctor, used for received options
+    ///
+    /// boost::shared_array allows sharing a buffer, but it requires that
+    /// different instances share pointer to the whole array, not point
+    /// to different elements in shared array. Therefore we need to share
+    /// pointer to the whole array and remember offset where data for
+    /// this option begins
+    ///
+    /// @param type option type (usually 4 for IA_NA, 25 for IA_PD)
+    /// @param buf buffer to be parsed
+    /// @param buf_len buffer length
+    /// @param offset offset in buffer
+    /// @param len number of bytes to parse
+    Option6IA(uint16_t type, const boost::shared_array<uint8_t>& buf,
+              unsigned int buf_len, unsigned int offset, unsigned int len);
+
+    /// Writes option in wire-format to buf, returns pointer to first unused
+    /// byte after stored option.
+    ///
+    /// @param buf buffer (option will be stored here)
+    /// @param buf_len (buffer length)
+    /// @param offset offset place where option should be stored
+    ///
+    /// @return offset to the first unused byte after stored option
+    unsigned int
+    pack(boost::shared_array<uint8_t>& buf, unsigned int buf_len,
+         unsigned int offset);
+
+    /// @brief Parses received buffer
+    ///
+    /// Parses received buffer and returns offset to the first unused byte after
+    /// parsed option.
+    ///
+    /// @param buf pointer to buffer
+    /// @param buf_len length of buf
+    /// @param offset offset, where start parsing option
+    /// @param parse_len how many bytes should be parsed
+    ///
+    /// @return offset after last parsed octet
+    virtual unsigned int
+    unpack(const boost::shared_array<uint8_t>& buf, unsigned int buf_len,
+           unsigned int offset, unsigned int parse_len);
+
+    /// Provides human readable text representation
+    ///
+    /// @param indent number of leading space characters
+    ///
+    /// @return string with text represenation
+    virtual std::string
+    toText(int indent = 0);
+
+    /// Sets T1 timer.
+    ///
+    /// @param t1 t1 value to be set
+    void setT1(unsigned int t1) { t1_=t1; }
+
+
+    /// Sets T2 timer.
+    ///
+    /// @param t2 t2 value to be set
+    void setT2(unsigned int t2) { t2_=t2; }
+
+    /// Returns IA identifier.
+    ///
+    /// @return IAID value.
+    ///
+    unsigned int getIAID() const { return iaid_; }
+
+    /// Returns T1 timer.
+    ///
+    /// @return T1 value.
+    unsigned int getT1() const { return t1_; }
+
+    /// Returns T2 timer.
+    ///
+    /// @return T2 value.
+    unsigned int getT2() const { return t2_; }
+
+    /// @brief returns complete length of option
+    ///
+    /// Returns length of this option, including option header and suboptions
+    ///
+    /// @return length of this option
+    virtual unsigned short
+    len();
+
+protected:
+
+    /// keeps IA identifier
+    unsigned int iaid_;
+
+    /// keeps T1 timer value
+    unsigned int t1_;
+
+    /// keeps T2 timer value
+    unsigned int t2_;
+};
+
+} // isc::dhcp namespace
+} // isc namespace
+
+#endif /* OPTION_IA_H_ */
diff --git a/src/lib/dhcp/option6_iaaddr.cc b/src/lib/dhcp/option6_iaaddr.cc
new file mode 100644
index 0000000..56b7ba0
--- /dev/null
+++ b/src/lib/dhcp/option6_iaaddr.cc
@@ -0,0 +1,129 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <stdint.h>
+#include <arpa/inet.h>
+#include <sstream>
+#include "exceptions/exceptions.h"
+
+#include "dhcp/libdhcp.h"
+#include "dhcp/option6_iaaddr.h"
+#include "dhcp/dhcp6.h"
+#include "asiolink/io_address.h"
+#include "util/io_utilities.h"
+
+using namespace std;
+using namespace isc;
+using namespace isc::dhcp;
+using namespace isc::asiolink;
+using namespace isc::util;
+
+Option6IAAddr::Option6IAAddr(unsigned short type,
+                             const isc::asiolink::IOAddress& addr,
+                             unsigned int pref, unsigned int valid)
+    :Option(V6, type), addr_(addr), preferred_(pref),
+     valid_(valid) {
+}
+
+Option6IAAddr::Option6IAAddr(unsigned short type,
+                             boost::shared_array<uint8_t> buf,
+                             unsigned int buf_len, unsigned int offset,
+                             unsigned int option_len)
+    :Option(V6, type), addr_("::") {
+    unpack(buf, buf_len, offset, option_len);
+}
+
+unsigned int
+Option6IAAddr::pack(boost::shared_array<uint8_t>& buf,
+                    unsigned int buf_len,
+                    unsigned int offset) {
+    if (len() > buf_len) {
+        isc_throw(OutOfRange, "Failed to pack IA option: len=" << len()
+                  << ", buffer=" << buf_len << ": too small buffer.");
+    }
+
+    *(uint16_t*)&buf[offset] = htons(type_);
+    offset += sizeof(uint16_t);
+    *(uint16_t*)&buf[offset] = htons(len() - OPTION6_HDR_LEN); // len() returns complete option
+    // length. len field contains length without 4-byte option header
+    offset += sizeof(uint16_t);
+
+    memcpy(&buf[offset], addr_.getAddress().to_v6().to_bytes().data(), 16);
+    offset += V6ADDRESS_LEN;
+
+    *(uint32_t*)&buf[offset] = htonl(preferred_);
+    offset += sizeof(uint32_t);
+    *(uint32_t*)&buf[offset] = htonl(valid_);
+    offset += sizeof(uint32_t);
+
+    // parse suboption (there shouldn't be any)
+    offset = LibDHCP::packOptions6(buf, buf_len, offset, options_);
+    return offset;
+}
+
+unsigned int
+Option6IAAddr::unpack(const boost::shared_array<uint8_t>& buf,
+                  unsigned int buf_len,
+                  unsigned int offset,
+                  unsigned int parse_len) {
+    if ( parse_len < OPTION6_IAADDR_LEN || offset + OPTION6_IAADDR_LEN > buf_len) {
+        isc_throw(OutOfRange, "Option " << type_ << " truncated");
+    }
+
+    // 16 bytes: IPv6 address
+    addr_ = IOAddress::from_bytes(AF_INET6, &buf[offset]);
+    offset += V6ADDRESS_LEN;
+
+    preferred_ = ntohl(*(uint32_t*)&buf[offset]);
+    offset += sizeof(uint32_t);
+
+    valid_ = ntohl(*(uint32_t*)&buf[offset]);
+    offset += sizeof(uint32_t);
+    offset = LibDHCP::unpackOptions6(buf, buf_len, offset,
+                                     parse_len - 24, options_);
+
+    return offset;
+}
+
+std::string Option6IAAddr::toText(int indent /* =0 */) {
+    stringstream tmp;
+    for (int i=0; i<indent; i++)
+        tmp << " ";
+
+    tmp << "type=" << type_ << "(IAADDR) addr=" << addr_.toText()
+        << ", preferred-lft=" << preferred_  << ", valid-lft="
+        << valid_ << endl;
+
+    for (Option6Collection::const_iterator opt=options_.begin();
+         opt!=options_.end();
+         ++opt) {
+        tmp << (*opt).second->toText(indent+2);
+    }
+    return tmp.str();
+}
+
+unsigned short Option6IAAddr::len() {
+
+    unsigned short length = OPTION6_HDR_LEN + OPTION6_IAADDR_LEN;
+
+    // length of all suboptions
+    // TODO implement:
+    // protected: unsigned short Option::lenHelper(int header_size);
+    for (Option::Option6Collection::iterator it = options_.begin();
+         it != options_.end();
+         ++it) {
+        length += (*it).second->len();
+    }
+    return (length);
+}
diff --git a/src/lib/dhcp/option6_iaaddr.h b/src/lib/dhcp/option6_iaaddr.h
new file mode 100644
index 0000000..60c5c48
--- /dev/null
+++ b/src/lib/dhcp/option6_iaaddr.h
@@ -0,0 +1,146 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef OPTION6_IAADDR_H_
+#define OPTION6_IAADDR_H_
+
+#include "asiolink/io_address.h"
+#include "dhcp/option.h"
+
+namespace isc {
+namespace dhcp {
+
+class Option6IAAddr: public Option {
+
+public:
+    /// length of the fixed part of the IAADDR option
+    static const size_t OPTION6_IAADDR_LEN = 24;
+
+    /// @brief ctor, used for options constructed (during transmission)
+    ///
+    /// @param type option type
+    /// @param addr reference to an address
+    /// @param preferred address preferred lifetime (in seconds)
+    /// @param valid address valid lifetime (in seconds)
+    Option6IAAddr(unsigned short type, const isc::asiolink::IOAddress& addr,
+                  unsigned int preferred, unsigned int valid);
+
+    /// ctor, used for received options
+    /// boost::shared_array allows sharing a buffer, but it requires that
+    /// different instances share pointer to the whole array, not point
+    /// to different elements in shared array. Therefore we need to share
+    /// pointer to the whole array and remember offset where data for
+    /// this option begins
+    ///
+    /// @param type option type
+    /// @param buf pointer to a buffer
+    /// @param offset offset to first data byte in that buffer
+    /// @param len data length of this option
+    Option6IAAddr(unsigned short type, boost::shared_array<uint8_t> buf,
+                  unsigned int buf_len, unsigned int offset, unsigned int len);
+
+    /// @brief Writes option in wire-format.
+    ///
+    /// Writes option in wire-format to buf, returns pointer to first unused
+    /// byte after stored option.
+    ///
+    /// @param buf pointer to a buffer
+    /// @param buf_len length of the buffer
+    /// @param offset offset to place, where option shout be stored
+    ///
+    /// @return offset to first unused byte after stored option
+    unsigned int
+    pack(boost::shared_array<uint8_t>& buf, unsigned int buf_len,
+         unsigned int offset);
+
+    /// @brief Parses buffer.
+    ///
+    /// Parses received buffer, returns offset to the first unused byte after
+    /// parsed option.
+    ///
+    /// @param buf pointer to buffer
+    /// @param buf_len length of buf
+    /// @param offset offset, where start parsing option
+    /// @param parse_len how many bytes should be parsed
+    ///
+    /// @return offset after last parsed octet
+    virtual unsigned int
+    unpack(const boost::shared_array<uint8_t>& buf,
+           unsigned int buf_len,
+           unsigned int offset,
+           unsigned int parse_len);
+
+    /// Returns string representation of the option.
+    ///
+    /// @param indent number of spaces before printing text
+    ///
+    /// @return string with text representation.
+    virtual std::string
+    toText(int indent = 0);
+
+
+    /// sets address in this option.
+    ///
+    /// @param addr address to be sent in this option
+    void setAddress(const isc::asiolink::IOAddress& addr) { addr_ = addr; }
+
+    /// Sets preferred lifetime (in seconds)
+    ///
+    /// @param pref address preferred lifetime (in seconds)
+    ///
+    void setPreferred(unsigned int pref) { preferred_=pref; }
+
+    /// Sets valid lifetime (in seconds).
+    ///
+    /// @param valid address valid lifetime (in seconds)
+    ///
+    void setValid(unsigned int valid) { valid_=valid; }
+
+    /// Returns  address contained within this option.
+    ///
+    /// @return address
+    isc::asiolink::IOAddress
+    getAddress() const { return addr_; }
+
+    /// Returns preferred lifetime of an address.
+    ///
+    /// @return preferred lifetime (in seconds)
+    unsigned int
+    getPreferred() const { return preferred_; }
+
+    /// Returns valid lifetime of an address.
+    ///
+    /// @return valid lifetime (in seconds)
+    unsigned int
+    getValid() const { return valid_; }
+
+    /// returns data length (data length + DHCPv4/DHCPv6 option header)
+    virtual unsigned short
+    len();
+
+protected:
+    /// contains an IPv6 address
+    isc::asiolink::IOAddress addr_;
+
+    /// contains preferred-lifetime timer (in seconds)
+    unsigned int preferred_;
+
+    /// contains valid-lifetime timer (in seconds)
+    unsigned int valid_;
+};
+
+} // isc::dhcp namespace
+} // isc namespace
+
+#endif /* OPTION_IA_H_ */
diff --git a/src/lib/dhcp/pkt6.cc b/src/lib/dhcp/pkt6.cc
new file mode 100644
index 0000000..1e4a553
--- /dev/null
+++ b/src/lib/dhcp/pkt6.cc
@@ -0,0 +1,224 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+
+#include "dhcp/dhcp6.h"
+#include "dhcp/pkt6.h"
+#include "dhcp/libdhcp.h"
+#include "exceptions/exceptions.h"
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+using namespace isc::dhcp;
+
+namespace isc {
+
+Pkt6::Pkt6(unsigned int dataLen, DHCPv6Proto proto /* = UDP */)
+    :data_len_(dataLen),
+     local_addr_("::"),
+     remote_addr_("::"),
+     iface_(""),
+     ifindex_(-1),
+     local_port_(-1),
+     remote_port_(-1),
+     proto_(proto),
+     msg_type_(-1),
+     transid_(rand()%0xffffff)
+{
+
+    data_ = boost::shared_array<uint8_t>(new uint8_t[dataLen]);
+    data_len_ = dataLen;
+}
+
+Pkt6::Pkt6(uint8_t msg_type,
+           unsigned int transid,
+           DHCPv6Proto proto /*= UDP*/)
+    :local_addr_("::"),
+     remote_addr_("::"),
+     iface_(""),
+     ifindex_(-1),
+     local_port_(-1),
+     remote_port_(-1),
+     proto_(proto),
+     msg_type_(msg_type),
+     transid_(transid) {
+
+    data_ = boost::shared_array<uint8_t>(new uint8_t[4]);
+    data_len_ = 4;
+}
+
+unsigned short
+Pkt6::len() {
+    unsigned int length = DHCPV6_PKT_HDR_LEN; // DHCPv6 header
+
+    for (Option::Option6Collection::iterator it = options_.begin();
+         it != options_.end();
+         ++it) {
+        length += (*it).second->len();
+    }
+
+    return (length);
+}
+
+
+bool
+Pkt6::pack() {
+    switch (proto_) {
+    case UDP:
+        return packUDP();
+    case TCP:
+        return packTCP();
+    default:
+        isc_throw(BadValue, "Invalid protocol specified (non-TCP, non-UDP)");
+    }
+    return (false); // never happens
+}
+
+bool
+Pkt6::packUDP() {
+    unsigned short length = len();
+    if (data_len_ < length) {
+        cout << "Previous len=" << data_len_ << ", allocating new buffer: len="
+             << length << endl;
+
+        // May throw exception if out of memory. That is rather fatal,
+        // so we don't catch this
+        data_ = boost::shared_array<uint8_t>(new uint8_t[length]);
+        data_len_ = length;
+    }
+
+    data_len_ = length;
+    try {
+        // DHCPv6 header: message-type (1 octect) + transaction id (3 octets)
+        data_[0] = msg_type_;
+
+        // store 3-octet transaction-id
+        data_[1] = (transid_ >> 16) & 0xff;
+        data_[2] = (transid_ >> 8) & 0xff;
+        data_[3] = (transid_) & 0xff;
+
+        // the rest are options
+        unsigned short offset = LibDHCP::packOptions6(data_, length,
+                                                      4/*offset*/,
+                                                      options_);
+
+        // sanity check
+        if (offset != length) {
+            isc_throw(OutOfRange, "Packet build failed: expected size="
+                      << length << ", actual len=" << offset);
+        }
+    }
+    catch (const Exception& e) {
+        cout << "Packet build failed:" << e.what() << endl;
+        return (false);
+    }
+    cout << "Packet built, len=" << len() << endl;
+    return (true);
+}
+
+bool
+Pkt6::packTCP() {
+    /// TODO Implement this function.
+    isc_throw(Unexpected, "DHCPv6 over TCP (bulk leasequery and failover)"
+              "not implemented yet.");
+}
+
+bool
+Pkt6::unpack() {
+    switch (proto_) {
+    case UDP:
+        return unpackUDP();
+    case TCP:
+        return unpackTCP();
+    default:
+        isc_throw(BadValue, "Invalid protocol specified (non-TCP, non-UDP)");
+    }
+    return (false); // never happens
+}
+
+bool
+Pkt6::unpackUDP() {
+    if (data_len_ < 4) {
+        std::cout << "DHCPv6 packet truncated. Only " << data_len_
+                  << " bytes. Need at least 4." << std::endl;
+        return (false);
+    }
+    msg_type_ = data_[0];
+    transid_ = ( (data_[1]) << 16 ) +
+        ((data_[2]) << 8) + (data_[3]);
+    transid_ = transid_ & 0xffffff;
+
+    unsigned int offset = LibDHCP::unpackOptions6(data_,
+                                                  data_len_,
+                                                  4, //offset
+                                                  data_len_ - 4,
+                                                  options_);
+    if (offset != data_len_) {
+        cout << "DHCPv6 packet contains trailing garbage. Parsed "
+             << offset << " bytes, packet is " << data_len_ << " bytes."
+             << endl;
+        // just a warning. Ignore trailing garbage and continue
+    }
+    return (true);
+}
+
+bool
+Pkt6::unpackTCP() {
+    isc_throw(Unexpected, "DHCPv6 over TCP (bulk leasequery and failover) "
+              "not implemented yet.");
+}
+
+
+std::string
+Pkt6::toText() {
+    stringstream tmp;
+    tmp << "localAddr=[" << local_addr_.toText() << "]:" << local_port_
+        << " remoteAddr=[" << remote_addr_.toText()
+        << "]:" << remote_port_ << endl;
+    tmp << "msgtype=" << msg_type_ << ", transid=0x" << hex << transid_
+        << dec << endl;
+    for (isc::dhcp::Option::Option6Collection::iterator opt=options_.begin();
+         opt != options_.end();
+         ++opt) {
+        tmp << opt->second->toText() << std::endl;
+    }
+    return tmp.str();
+}
+
+boost::shared_ptr<isc::dhcp::Option>
+Pkt6::getOption(unsigned short opt_type) {
+    isc::dhcp::Option::Option6Collection::const_iterator x = options_.find(opt_type);
+    if (x!=options_.end()) {
+        return (*x).second;
+    }
+    return boost::shared_ptr<isc::dhcp::Option>(); // NULL
+}
+
+void
+Pkt6::addOption(boost::shared_ptr<Option> opt) {
+    options_.insert(pair<int, boost::shared_ptr<Option> >(opt->getType(), opt));
+}
+
+bool
+Pkt6::delOption(unsigned short type) {
+    isc::dhcp::Option::Option6Collection::iterator x = options_.find(type);
+    if (x!=options_.end()) {
+        options_.erase(x);
+        return (true); // delete successful
+    }
+    return (false); // can't find option to be deleted
+}
+
+};
diff --git a/src/lib/dhcp/pkt6.h b/src/lib/dhcp/pkt6.h
new file mode 100644
index 0000000..35bccbc
--- /dev/null
+++ b/src/lib/dhcp/pkt6.h
@@ -0,0 +1,234 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef PKT6_H
+#define PKT6_H
+
+#include <iostream>
+#include <boost/shared_ptr.hpp>
+#include <boost/shared_array.hpp>
+#include "asiolink/io_address.h"
+#include "option.h"
+
+namespace isc {
+
+namespace dhcp {
+
+class Pkt6 {
+public:
+    /// specifes DHCPv6 packet header length
+    const static size_t DHCPV6_PKT_HDR_LEN = 4;
+
+    /// DHCPv6 transport protocol
+    enum DHCPv6Proto {
+        UDP = 0, // most packets are UDP
+        TCP = 1  // there are TCP DHCPv6 packets (bulk leasequery, failover)
+    };
+
+    /// Constructor, used in replying to a message
+    ///
+    /// @param msg_type type of message (SOLICIT=1, ADVERTISE=2, ...)
+    /// @param transid transaction-id
+    /// @param proto protocol (TCP or UDP)
+    Pkt6(unsigned char msg_type,
+         unsigned int transid,
+         DHCPv6Proto proto = UDP);
+
+    /// Constructor, used in message transmission
+    ///
+    /// Creates new message. Transaction-id will randomized.
+    ///
+    /// @param len size of buffer to be allocated for this packet.
+    /// @param proto protocol (usually UDP, but TCP will be supported eventually)
+    Pkt6(unsigned int len, DHCPv6Proto proto = UDP);
+
+    /// @brief Prepares on-wire format.
+    ///
+    /// Prepares on-wire format of message and all its options.
+    /// Options must be stored in options_ field.
+    /// Output buffer will be stored in data_. Length
+    /// will be set in data_len_.
+    ///
+    /// @return true if packing procedure was successful
+    bool
+    pack();
+
+    /// @brief Dispatch method that handles binary packet parsing.
+    ///
+    /// This method calls appropriate dispatch function (unpackUDP or
+    /// unpackTCP).
+    ///
+    /// @return true if parsing was successful
+    bool
+    unpack();
+
+    /// Returns protocol of this packet (UDP or TCP)
+    ///
+    /// @return protocol type
+    DHCPv6Proto
+    getProto();
+
+    /// Sets protocol of this packet.
+    ///
+    /// @param proto protocol (UDP or TCP)
+    ///
+    void
+    setProto(DHCPv6Proto proto = UDP) { proto_ = proto; }
+
+    /// @brief Returns text representation of the packet.
+    ///
+    /// This function is useful mainly for debugging.
+    ///
+    /// @return string with text representation
+    std::string
+    toText();
+
+    /// @brief Returns calculated length of the packet.
+    ///
+    /// This function returns size of required buffer to buld this packet.
+    /// To use that function, options_ field must be set.
+    ///
+    /// @return number of bytes required to build this packet
+    unsigned short
+    len();
+
+    /// Returns message type (e.g. 1 = SOLICIT)
+    ///
+    /// @return message type
+    unsigned char
+    getType() { return (msg_type_); }
+
+    /// Sets message type (e.g. 1 = SOLICIT)
+    ///
+    /// @param type message type to be set
+    void setType(unsigned char type) { msg_type_=type; };
+
+    /// Returns value of transaction-id field
+    ///
+    /// @return transaction-id
+    unsigned int getTransid() { return (transid_); };
+
+    /// Adds an option to this packet.
+    ///
+    /// @param opt option to be added.
+    void addOption(boost::shared_ptr<isc::dhcp::Option> opt);
+
+    /// @brief Returns the first option of specified type.
+    ///
+    /// Returns the first option of specified type. Note that in DHCPv6 several
+    /// instances of the same option are allowed (and frequently used).
+    /// See getOptions().
+    ///
+    /// @param opt_type option type we are looking for
+    ///
+    /// @return pointer to found option (or NULL)
+    boost::shared_ptr<isc::dhcp::Option>
+    getOption(unsigned short type);
+
+    /// Attempts to delete first suboption of requested type
+    ///
+    /// @param type Type of option to be deleted.
+    ///
+    /// @return true if option was deleted, false if no such option existed
+    bool
+    delOption(unsigned short type);
+
+    /// TODO need getter/setter wrappers
+    ///      and hide following fields as protected
+
+    /// buffer that holds memory. It is shared_array as options may
+    /// share pointer to this buffer
+    boost::shared_array<uint8_t> data_;
+
+    /// length of the data
+    unsigned int data_len_;
+
+    /// local address (dst if receiving packet, src if sending packet)
+    isc::asiolink::IOAddress local_addr_;
+
+    /// remote address (src if receiving packet, dst if sending packet)
+    isc::asiolink::IOAddress remote_addr_;
+
+    /// name of the network interface the packet was received/to be sent over
+    std::string iface_;
+
+    /// @brief interface index
+    ///
+    /// interface index (each network interface has assigned unique ifindex
+    /// it is functional equvalent of name, but sometimes more useful, e.g.
+    /// when using crazy systems that allow spaces in interface names
+    /// e.g. windows
+    int ifindex_;
+
+    /// local TDP or UDP port
+    int local_port_;
+
+    /// remote TCP or UDP port
+    int remote_port_;
+
+    /// TODO Need to implement getOptions() as well
+
+    /// collection of options present in this message
+    isc::dhcp::Option::Option6Collection options_;
+
+protected:
+    /// Builds on wire packet for TCP transmission.
+    ///
+    /// TODO This function is not implemented yet.
+    ///
+    /// @return true, if build was successful
+    bool packTCP();
+
+    /// Builds on wire packet for UDP transmission.
+    ///
+    /// @return true, if build was successful
+    bool packUDP();
+
+    /// @brief Parses on-wire form of TCP DHCPv6 packet.
+    ///
+    /// Parses received packet, stored in on-wire format in data_.
+    /// data_len_ must be set to indicate data length.
+    /// Will create a collection of option objects that will
+    /// be stored in options_ container.
+    ///
+    /// TODO This function is not implemented yet.
+    ///
+    /// @return true, if build was successful
+    bool unpackTCP();
+
+    /// @brief Parses on-wire form of UDP DHCPv6 packet.
+    ///
+    /// Parses received packet, stored in on-wire format in data_.
+    /// data_len_ must be set to indicate data length.
+    /// Will create a collection of option objects that will
+    /// be stored in options_ container.
+    ///
+    /// @return true, if build was successful
+    bool unpackUDP();
+
+    /// UDP (usually) or TCP (bulk leasequery or failover)
+    DHCPv6Proto proto_;
+
+    /// DHCPv6 message type
+    int msg_type_;
+
+    /// DHCPv6 transaction-id
+    unsigned int transid_;
+}; // Pkt6 class
+
+} // isc::dhcp namespace
+
+} // isc namespace
+
+#endif
diff --git a/src/lib/dhcp/tests/Makefile.am b/src/lib/dhcp/tests/Makefile.am
new file mode 100644
index 0000000..3fce27e
--- /dev/null
+++ b/src/lib/dhcp/tests/Makefile.am
@@ -0,0 +1,42 @@
+SUBDIRS = .
+
+AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS += -I$(top_srcdir)/src/lib/asiolink
+AM_CPPFLAGS += -I$(top_builddir)/src/lib/asiolink
+AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CXXFLAGS = $(B10_CXXFLAGS)
+
+if USE_STATIC_LINK
+AM_LDFLAGS = -static
+endif
+
+CLEANFILES = *.gcno *.gcda
+
+TESTS =
+if HAVE_GTEST
+TESTS += libdhcp_unittests
+libdhcp_unittests_SOURCES  = run_unittests.cc
+libdhcp_unittests_SOURCES += ../libdhcp.h ../libdhcp.cc libdhcp_unittest.cc
+libdhcp_unittests_SOURCES += ../option6_iaaddr.h ../option6_iaaddr.cc option6_iaaddr_unittest.cc
+libdhcp_unittests_SOURCES += ../option6_ia.h ../option6_ia.cc option6_ia_unittest.cc
+libdhcp_unittests_SOURCES += ../option6_addrlst.h ../option6_addrlst.cc option6_addrlst_unittest.cc
+libdhcp_unittests_SOURCES += ../option.h ../option.cc option_unittest.cc
+libdhcp_unittests_SOURCES += ../pkt6.h ../pkt6.cc pkt6_unittest.cc
+
+libdhcp_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES)
+libdhcp_unittests_LDFLAGS  = $(AM_LDFLAGS)  $(GTEST_LDFLAGS)
+
+libdhcp_unittests_CXXFLAGS = $(AM_CXXFLAGS)
+if USE_CLANGPP
+# This is to workaround unused variables tcout and tcerr in
+# log4cplus's streams.h.
+libdhcp_unittests_CXXFLAGS += -Wno-unused-variable
+endif
+libdhcp_unittests_LDADD  = $(GTEST_LDADD)
+libdhcp_unittests_LDADD += $(top_builddir)/src/lib/log/liblog.la
+libdhcp_unittests_LDADD += $(top_builddir)/src/lib/util/libutil.la
+libdhcp_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
+libdhcp_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
+endif
+
+noinst_PROGRAMS = $(TESTS)
diff --git a/src/lib/dhcp/tests/libdhcp_unittest.cc b/src/lib/dhcp/tests/libdhcp_unittest.cc
new file mode 100644
index 0000000..d9d7c47
--- /dev/null
+++ b/src/lib/dhcp/tests/libdhcp_unittest.cc
@@ -0,0 +1,137 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+#include <iostream>
+#include <sstream>
+
+#include <arpa/inet.h>
+#include <gtest/gtest.h>
+
+#include "dhcp/libdhcp.h"
+#include "config.h"
+
+using namespace std;
+using namespace isc;
+using namespace isc::dhcp;
+
+namespace {
+class LibDhcpTest : public ::testing::Test {
+public:
+    LibDhcpTest() {
+    }
+};
+
+static const uint8_t packed[] = {
+    0, 12, 0, 5, 100, 101, 102, 103, 104, // opt1 (9 bytes)
+    0, 13, 0, 3, 105, 106, 107, // opt2 (7 bytes)
+    0, 14, 0, 2, 108, 109, // opt3 (6 bytes)
+    1,  0, 0, 4, 110, 111, 112, 113, // opt4 (8 bytes)
+    1,  1, 0, 1, 114 // opt5 (5 bytes)
+};
+
+TEST_F(LibDhcpTest, packOptions6) {
+    boost::shared_array<uint8_t> buf(new uint8_t[512]);
+    isc::dhcp::Option::Option6Collection opts; // list of options
+
+    // generate content for options
+    for (int i = 0; i < 64; i++) {
+        buf[i]=i+100;
+    }
+
+    boost::shared_ptr<Option> opt1(new Option(Option::V6, 12, buf, 0, 5));
+    boost::shared_ptr<Option> opt2(new Option(Option::V6, 13, buf, 5, 3));
+    boost::shared_ptr<Option> opt3(new Option(Option::V6, 14, buf, 8, 2));
+    boost::shared_ptr<Option> opt4(new Option(Option::V6,256, buf,10, 4));
+    boost::shared_ptr<Option> opt5(new Option(Option::V6,257, buf,14, 1));
+
+    opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt1));
+    opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt2));
+    opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt3));
+    opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt4));
+    opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt5));
+
+    unsigned int offset;
+    EXPECT_NO_THROW ({
+         offset = LibDHCP::packOptions6(buf, 512, 100, opts);
+    });
+    EXPECT_EQ(135, offset); // options should take 35 bytes
+    EXPECT_EQ(0, memcmp(&buf[100], packed, 35) );
+}
+
+TEST_F(LibDhcpTest, unpackOptions6) {
+
+    // just couple of random options
+    // Option is used as a simple option implementation
+    // More advanced uses are validated in tests dedicated for
+    // specific derived classes.
+    isc::dhcp::Option::Option6Collection options; // list of options
+
+    // we can't use packed directly, as shared_array would try to
+    // free it eventually
+    boost::shared_array<uint8_t> buf(new uint8_t[512]);
+    memcpy(&buf[0], packed, 35);
+
+    unsigned int offset;
+    EXPECT_NO_THROW ({
+        offset = LibDHCP::unpackOptions6(buf, 512, 0, 35, options);
+    });
+
+    EXPECT_EQ(35, offset); // parsed first 35 bytes (offset 0..34)
+    EXPECT_EQ(options.size(), 5); // there should be 5 options
+
+    isc::dhcp::Option::Option6Collection::const_iterator x = options.find(12);
+    ASSERT_FALSE(x == options.end()); // option 1 should exist
+    EXPECT_EQ(12, x->second->getType());  // this should be option 12
+    ASSERT_EQ(9, x->second->len()); // it should be of length 9
+    EXPECT_EQ(0, memcmp(x->second->getData(), packed+4, 5)); // data len=5
+
+    x = options.find(13);
+    ASSERT_FALSE(x == options.end()); // option 13 should exist
+    EXPECT_EQ(13, x->second->getType());  // this should be option 13
+    ASSERT_EQ(7, x->second->len()); // it should be of length 7
+    EXPECT_EQ(0, memcmp(x->second->getData(), packed+13, 3)); // data len=3
+
+    x = options.find(14);
+    ASSERT_FALSE(x == options.end()); // option 3 should exist
+    EXPECT_EQ(14, x->second->getType());  // this should be option 14
+    ASSERT_EQ(6, x->second->len()); // it should be of length 6
+    EXPECT_EQ(0, memcmp(x->second->getData(), packed+20, 2)); // data len=2
+
+    x = options.find(256);
+    ASSERT_FALSE(x == options.end()); // option 256 should exist
+    EXPECT_EQ(256, x->second->getType());  // this should be option 256
+    ASSERT_EQ(8, x->second->len()); // it should be of length 7
+    EXPECT_EQ(0, memcmp(x->second->getData(), packed+26, 4)); // data len=4
+
+    x = options.find(257);
+    ASSERT_FALSE(x == options.end()); // option 257 should exist
+    EXPECT_EQ(257, x->second->getType());  // this should be option 257
+    ASSERT_EQ(5, x->second->len()); // it should be of length 5
+    EXPECT_EQ(0, memcmp(x->second->getData(), packed+34, 1)); // data len=1
+
+    x = options.find(0);
+    EXPECT_TRUE(x == options.end()); // option 0 not found
+
+    x = options.find(1); // 1 is htons(256) on little endians. Worth checking
+    EXPECT_TRUE(x == options.end()); // option 1 not found
+
+    x = options.find(2);
+    EXPECT_TRUE(x == options.end()); // option 2 not found
+
+    x = options.find(32000);
+    EXPECT_TRUE(x == options.end()); // option 32000 not found
+}
+
+}
diff --git a/src/lib/dhcp/tests/option6_addrlst_unittest.cc b/src/lib/dhcp/tests/option6_addrlst_unittest.cc
new file mode 100644
index 0000000..2a2fc1a
--- /dev/null
+++ b/src/lib/dhcp/tests/option6_addrlst_unittest.cc
@@ -0,0 +1,231 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+#include <iostream>
+#include <sstream>
+
+#include <arpa/inet.h>
+#include <gtest/gtest.h>
+
+#include "io_address.h"
+#include "dhcp/dhcp6.h"
+#include "dhcp/option.h"
+#include "dhcp/option6_addrlst.h"
+
+using namespace std;
+using namespace isc;
+using namespace isc::dhcp;
+using namespace isc::asiolink;
+
+namespace {
+class Option6AddrLstTest : public ::testing::Test {
+public:
+    Option6AddrLstTest() {
+    }
+};
+
+TEST_F(Option6AddrLstTest, basic) {
+
+    // limiting tests to just a 2001:db8::/32 as is *wrong*.
+    // Good tests check corner cases as well.
+    // ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff checks
+    // for integer overflow
+    // ff02::face:b00c checks if multicast addresses
+    // can be represented properly.
+
+    uint8_t sampledata[] = {
+        // 2001:db8:1::dead:beef
+        0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0, 0,
+        0, 0, 0, 0, 0xde, 0xad, 0xbe, 0xef,
+
+        // ff02::face:b00c
+        0xff, 02, 0, 0, 0, 0, 0 , 0,
+        0, 0, 0, 0, 0xfa, 0xce, 0xb0, 0x0c,
+
+        // ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+    };
+
+    uint8_t expected1[] = {
+        D6O_NAME_SERVERS/256, D6O_NAME_SERVERS%256,//type
+        0, 16, // len = 16 (1 address)
+        0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0, 0,
+        0, 0, 0, 0, 0xde, 0xad, 0xbe, 0xef,
+
+    };
+
+    uint8_t expected2[] = {
+        D6O_SIP_SERVERS_ADDR/256, D6O_SIP_SERVERS_ADDR%256,
+        0, 32, // len = 32 (2 addresses)
+        // 2001:db8:1::dead:beef
+        0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0, 0,
+        0, 0, 0, 0, 0xde, 0xad, 0xbe, 0xef,
+
+        // ff02::face:b00c
+        0xff, 02, 0, 0, 0, 0, 0 , 0,
+        0, 0, 0, 0, 0xfa, 0xce, 0xb0, 0x0c,
+
+        // ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+    };
+
+    uint8_t expected3[] = {
+        D6O_NIS_SERVERS/256, D6O_NIS_SERVERS%256,
+        0, 48,
+        // 2001:db8:1::dead:beef
+        0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0, 0,
+        0, 0, 0, 0, 0xde, 0xad, 0xbe, 0xef,
+
+        // ff02::face:b00c
+        0xff, 02, 0, 0, 0, 0, 0 , 0,
+        0, 0, 0, 0, 0xfa, 0xce, 0xb0, 0x0c,
+
+        // ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+    };
+
+    boost::shared_array<uint8_t> buf(new uint8_t[300]);
+    for (int i = 0; i < 300; i++)
+        buf[i] = 0;
+
+    memcpy(&buf[0], sampledata, 48);
+
+    // just a single address
+    Option6AddrLst* opt1 = 0;
+    EXPECT_NO_THROW(
+        opt1 = new Option6AddrLst(D6O_NAME_SERVERS, buf, 128, 0, 16);
+    );
+
+    EXPECT_EQ(D6O_NAME_SERVERS, opt1->getType());
+    EXPECT_EQ(20, opt1->len());
+    Option6AddrLst::AddressContainer addrs = opt1->getAddresses();
+    ASSERT_EQ(1, addrs.size());
+    IOAddress addr = addrs[0];
+    EXPECT_EQ("2001:db8:1::dead:beef", addr.toText());
+
+    // pack this option again in the same buffer, but in
+    // different place
+    int offset = opt1->pack(buf,300, 100);
+
+    EXPECT_EQ(120, offset);
+    EXPECT_EQ( 0, memcmp(expected1, &buf[100], 20) );
+
+    // two addresses
+    Option6AddrLst* opt2 = 0;
+    EXPECT_NO_THROW(
+        opt2 = new Option6AddrLst(D6O_SIP_SERVERS_ADDR, buf, 128, 0, 32);
+    );
+    EXPECT_EQ(D6O_SIP_SERVERS_ADDR, opt2->getType());
+    EXPECT_EQ(36, opt2->len());
+    addrs = opt2->getAddresses();
+    ASSERT_EQ(2, addrs.size());
+    EXPECT_EQ("2001:db8:1::dead:beef", addrs[0].toText());
+    EXPECT_EQ("ff02::face:b00c", addrs[1].toText());
+
+    // pack this option again in the same buffer, but in
+    // different place
+    offset = opt2->pack(buf,300, 150);
+
+    EXPECT_EQ(150+36, offset);
+    EXPECT_EQ( 0, memcmp(expected2, &buf[150], 36));
+
+    // three addresses
+    Option6AddrLst* opt3 = 0;
+    EXPECT_NO_THROW(
+        opt3 = new Option6AddrLst(D6O_NIS_SERVERS, buf, 128, 0, 48);
+    );
+
+    EXPECT_EQ(D6O_NIS_SERVERS, opt3->getType());
+    EXPECT_EQ(52, opt3->len());
+    addrs = opt3->getAddresses();
+    ASSERT_EQ(3, addrs.size());
+    EXPECT_EQ("2001:db8:1::dead:beef", addrs[0].toText());
+    EXPECT_EQ("ff02::face:b00c", addrs[1].toText());
+    EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", addrs[2].toText());
+
+    // pack this option again in the same buffer, but in
+    // different place
+    offset = opt3->pack(buf,300, 200);
+
+    EXPECT_EQ(252, offset);
+    EXPECT_EQ( 0, memcmp(expected3, &buf[200], 52) );
+
+    EXPECT_NO_THROW(
+        delete opt1;
+        delete opt2;
+        delete opt3;
+    );
+}
+
+TEST_F(Option6AddrLstTest, constructors) {
+
+    Option6AddrLst* opt1 = 0;
+    EXPECT_NO_THROW(
+        opt1 = new Option6AddrLst(1234, IOAddress("::1"));
+    );
+    EXPECT_EQ(1234, opt1->getType());
+
+    Option6AddrLst::AddressContainer addrs = opt1->getAddresses();
+    ASSERT_EQ(1, addrs.size() );
+    EXPECT_EQ("::1", addrs[0].toText());
+
+    addrs.clear();
+    addrs.push_back(IOAddress(string("fe80::1234")));
+    addrs.push_back(IOAddress(string("2001:db8:1::baca")));
+
+    Option6AddrLst* opt2 = 0;
+    EXPECT_NO_THROW(
+        opt2 = new Option6AddrLst(5678, addrs);
+    );
+
+    Option6AddrLst::AddressContainer check = opt2->getAddresses();
+    ASSERT_EQ(2, check.size() );
+    EXPECT_EQ("fe80::1234", check[0].toText());
+    EXPECT_EQ("2001:db8:1::baca", check[1].toText());
+
+    EXPECT_NO_THROW(
+        delete opt1;
+        delete opt2;
+    );
+}
+
+TEST_F(Option6AddrLstTest, setAddress) {
+    Option6AddrLst* opt1 = 0;
+    EXPECT_NO_THROW(
+        opt1 = new Option6AddrLst(1234, IOAddress("::1"));
+    );
+    opt1->setAddress(IOAddress("2001:db8:1::2"));
+    /// TODO It used to be ::2 address, but io_address represents
+    /// it as ::0.0.0.2. Purpose of this test is to verify
+    /// that setAddress() works, not deal with subtleties of
+    /// io_address handling of IPv4-mapped IPv6 addresses, we
+    /// switched to a more common address. User interested
+    /// in pursuing this matter further is encouraged to look
+    /// at section 2.5.5 of RFC4291 (and possibly implement
+    /// a test for IOAddress)
+
+    Option6AddrLst::AddressContainer addrs = opt1->getAddresses();
+    ASSERT_EQ(1, addrs.size() );
+    EXPECT_EQ("2001:db8:1::2", addrs[0].toText());
+
+    EXPECT_NO_THROW(
+        delete opt1;
+    );
+}
+
+} // namespace
diff --git a/src/lib/dhcp/tests/option6_ia_unittest.cc b/src/lib/dhcp/tests/option6_ia_unittest.cc
new file mode 100644
index 0000000..ac4127a
--- /dev/null
+++ b/src/lib/dhcp/tests/option6_ia_unittest.cc
@@ -0,0 +1,262 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+#include <iostream>
+#include <sstream>
+
+#include <arpa/inet.h>
+#include <gtest/gtest.h>
+
+#include <boost/shared_array.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include "dhcp/dhcp6.h"
+#include "dhcp/option.h"
+#include "dhcp/option6_ia.h"
+#include "dhcp/option6_iaaddr.h"
+
+using namespace std;
+using namespace isc;
+using namespace isc::dhcp;
+using namespace isc::asiolink;
+
+namespace {
+class Option6IATest : public ::testing::Test {
+public:
+    Option6IATest() {
+    }
+};
+
+TEST_F(Option6IATest, basic) {
+
+    boost::shared_array<uint8_t> simple_buf(new uint8_t[128]);
+    for (int i = 0; i < 128; i++)
+        simple_buf[i] = 0;
+    simple_buf[0] = 0xa1; // iaid
+    simple_buf[1] = 0xa2;
+    simple_buf[2] = 0xa3;
+    simple_buf[3] = 0xa4;
+
+    simple_buf[4] = 0x81; // T1
+    simple_buf[5] = 0x02;
+    simple_buf[6] = 0x03;
+    simple_buf[7] = 0x04;
+
+    simple_buf[8] = 0x84; // T2
+    simple_buf[9] = 0x03;
+    simple_buf[10] = 0x02;
+    simple_buf[11] = 0x01;
+
+    // create an option
+    // unpack() is called from constructor
+    Option6IA* opt = new Option6IA(D6O_IA_NA,
+                                   simple_buf,
+                                   128,
+                                   0,
+                                   12);
+
+    EXPECT_EQ(D6O_IA_NA, opt->getType());
+    EXPECT_EQ(0xa1a2a3a4, opt->getIAID());
+    EXPECT_EQ(0x81020304, opt->getT1());
+    EXPECT_EQ(0x84030201, opt->getT2());
+
+    // pack this option again in the same buffer, but in
+    // different place
+
+    // test for pack()
+    int offset = opt->pack(simple_buf, 128, 60);
+
+    // 4 bytes header + 4 bytes content
+    EXPECT_EQ(12, opt->len() - 4);
+    EXPECT_EQ(D6O_IA_NA, opt->getType());
+
+    EXPECT_EQ(offset, 76); // 60 + lenght(IA_NA) = 76
+
+    // check if pack worked properly:
+    // if option type is correct
+    EXPECT_EQ(D6O_IA_NA, simple_buf[60]*256 + simple_buf[61]);
+
+    // if option length is correct
+    EXPECT_EQ(12, simple_buf[62]*256 + simple_buf[63]);
+
+    // if iaid is correct
+    unsigned int iaid = htonl(*(unsigned int*)&simple_buf[64]);
+    EXPECT_EQ(0xa1a2a3a4, iaid );
+
+   // if T1 is correct
+    EXPECT_EQ(0x81020304, (simple_buf[68] << 24) +
+                          (simple_buf[69] << 16) +
+                          (simple_buf[70] << 8) +
+                          (simple_buf[71]) );
+
+    // if T1 is correct
+    EXPECT_EQ(0x84030201, (simple_buf[72] << 24) +
+                          (simple_buf[73] << 16) +
+                          (simple_buf[74] << 8) +
+                          (simple_buf[75]) );
+
+    EXPECT_NO_THROW(
+        delete opt;
+    );
+}
+
+TEST_F(Option6IATest, simple) {
+    boost::shared_array<uint8_t> simple_buf(new uint8_t[128]);
+    for (int i = 0; i < 128; i++)
+        simple_buf[i] = 0;
+
+    Option6IA * ia = new Option6IA(D6O_IA_NA, 1234);
+    ia->setT1(2345);
+    ia->setT2(3456);
+
+    EXPECT_EQ(D6O_IA_NA, ia->getType());
+    EXPECT_EQ(1234, ia->getIAID());
+    EXPECT_EQ(2345, ia->getT1());
+    EXPECT_EQ(3456, ia->getT2());
+
+    EXPECT_NO_THROW(
+        delete ia;
+    );
+}
+
+// test if option can build suboptions
+TEST_F(Option6IATest, suboptions_pack) {
+    boost::shared_array<uint8_t> buf(new uint8_t[128]);
+    for (int i=0; i<128; i++)
+        buf[i] = 0;
+    buf[0] = 0xff;
+    buf[1] = 0xfe;
+    buf[2] = 0xfc;
+
+    Option6IA * ia = new Option6IA(D6O_IA_NA, 0x13579ace);
+    ia->setT1(0x2345);
+    ia->setT2(0x3456);
+
+    boost::shared_ptr<Option> sub1(new Option(Option::V6,
+                                              0xcafe));
+
+    boost::shared_ptr<Option6IAAddr> addr1(
+        new Option6IAAddr(D6O_IAADDR, IOAddress("2001:db8:1234:5678::abcd"),
+                          0x5000, 0x7000));
+
+    ia->addOption(sub1);
+    ia->addOption(addr1);
+
+    ASSERT_EQ(28, addr1->len());
+    ASSERT_EQ(4, sub1->len());
+    ASSERT_EQ(48, ia->len());
+
+    uint8_t expected[] = {
+        D6O_IA_NA/256, D6O_IA_NA%256, // type
+        0, 44, // length
+        0x13, 0x57, 0x9a, 0xce, // iaid
+        0, 0, 0x23, 0x45,  // T1
+        0, 0, 0x34, 0x56,  // T2
+
+        // iaaddr suboption
+        D6O_IAADDR/256, D6O_IAADDR%256, // type
+        0, 24, // len
+        0x20, 0x01, 0xd, 0xb8, 0x12,0x34, 0x56, 0x78,
+        0, 0, 0, 0, 0, 0, 0xab, 0xcd, // IP address
+        0, 0, 0x50, 0, // preferred-lifetime
+        0, 0, 0x70, 0, // valid-lifetime
+
+        // suboption
+        0xca, 0xfe, // type
+        0, 0 // len
+    };
+
+    int offset = ia->pack(buf, 128, 10);
+    ASSERT_EQ(offset, 10 + 48);
+
+    EXPECT_EQ(0, memcmp(&buf[10], expected, 48));
+
+    EXPECT_NO_THROW(
+        delete ia;
+    );
+}
+
+// test if option can parse suboptions
+TEST_F(Option6IATest, suboptions_unpack) {
+
+
+    uint8_t expected[] = {
+        D6O_IA_NA/256, D6O_IA_NA%256, // type
+        0, 28, // length
+        0x13, 0x57, 0x9a, 0xce, // iaid
+        0, 0, 0x23, 0x45,  // T1
+        0, 0, 0x34, 0x56,  // T2
+
+        // iaaddr suboption
+        D6O_IAADDR/256, D6O_IAADDR%256, // type
+        0, 24, // len
+        0x20, 0x01, 0xd, 0xb8, 0x12,0x34, 0x56, 0x78,
+        0, 0, 0, 0, 0, 0, 0xab, 0xcd, // IP address
+        0, 0, 0x50, 0, // preferred-lifetime
+        0, 0, 0x70, 0, // valid-lifetime
+
+        // suboption
+        0xca, 0xfe, // type
+        0, 0 // len
+    };
+
+    boost::shared_array<uint8_t> buf(new uint8_t[128]);
+    for (int i = 0; i < 128; i++)
+        buf[i] = 0;
+    memcpy(&buf[0], expected, 48);
+
+    Option6IA* ia = 0;
+    EXPECT_NO_THROW({
+        ia = new Option6IA(D6O_IA_NA, buf, 128, 4, 44);
+        cout << "Parsed option:" << endl << ia->toText() << endl;
+    });
+    ASSERT_TRUE(ia);
+
+    EXPECT_EQ(D6O_IA_NA, ia->getType());
+    EXPECT_EQ(0x13579ace, ia->getIAID());
+    EXPECT_EQ(0x2345, ia->getT1());
+    EXPECT_EQ(0x3456, ia->getT2());
+
+    boost::shared_ptr<Option> subopt = ia->getOption(D6O_IAADDR);
+    ASSERT_NE(boost::shared_ptr<Option>(), subopt); // non-NULL
+
+    // checks for address option
+    Option6IAAddr * addr = dynamic_cast<Option6IAAddr*>(subopt.get());
+    ASSERT_TRUE(NULL != addr);
+
+    EXPECT_EQ(D6O_IAADDR, addr->getType());
+    EXPECT_EQ(28, addr->len());
+    EXPECT_EQ(0x5000, addr->getPreferred());
+    EXPECT_EQ(0x7000, addr->getValid());
+    EXPECT_EQ("2001:db8:1234:5678::abcd", addr->getAddress().toText());
+
+    // checks for dummy option
+    subopt = ia->getOption(0xcafe);
+    ASSERT_TRUE(subopt); // should be non-NULL
+
+    EXPECT_EQ(0xcafe, subopt->getType());
+    EXPECT_EQ(4, subopt->len());
+    // there should be no data at all
+    EXPECT_EQ(static_cast<void*>(NULL), subopt->getData());
+
+    subopt = ia->getOption(1); // get option 1
+    ASSERT_FALSE(subopt); // should be NULL
+
+    EXPECT_NO_THROW(
+        delete ia;
+    );
+}
+
+}
diff --git a/src/lib/dhcp/tests/option6_iaaddr_unittest.cc b/src/lib/dhcp/tests/option6_iaaddr_unittest.cc
new file mode 100644
index 0000000..f92304e
--- /dev/null
+++ b/src/lib/dhcp/tests/option6_iaaddr_unittest.cc
@@ -0,0 +1,101 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+#include <iostream>
+#include <sstream>
+
+#include <arpa/inet.h>
+#include <gtest/gtest.h>
+
+#include "dhcp/dhcp6.h"
+#include "dhcp/option.h"
+#include "dhcp/option6_iaaddr.h"
+
+using namespace std;
+using namespace isc;
+using namespace isc::dhcp;
+
+namespace {
+class Option6IAAddrTest : public ::testing::Test {
+public:
+    Option6IAAddrTest() {
+    }
+};
+
+TEST_F(Option6IAAddrTest, basic) {
+
+    boost::shared_array<uint8_t> simple_buf(new uint8_t[128]);
+    for (int i = 0; i < 128; i++)
+        simple_buf[i] = 0;
+    simple_buf[0] = 0x20;
+    simple_buf[1] = 0x01;
+    simple_buf[2] = 0x0d;
+    simple_buf[3] = 0xb8;
+    simple_buf[4] = 0x00;
+    simple_buf[5] = 0x01;
+    simple_buf[12] = 0xde;
+    simple_buf[13] = 0xad;
+    simple_buf[14] = 0xbe;
+    simple_buf[15] = 0xef; // 2001:db8:1::dead:beef
+
+    simple_buf[16] = 0x00;
+    simple_buf[17] = 0x00;
+    simple_buf[18] = 0x03;
+    simple_buf[19] = 0xe8; // 1000
+
+    simple_buf[20] = 0xb2;
+    simple_buf[21] = 0xd0;
+    simple_buf[22] = 0x5e;
+    simple_buf[23] = 0x00; // 3,000,000,000
+
+    // create an option (unpack content)
+    Option6IAAddr* opt = new Option6IAAddr(D6O_IAADDR,
+                                           simple_buf,
+                                           128,
+                                           0,
+                                           24);
+
+    // pack this option again in the same buffer, but in
+    // different place
+    int offset = opt->pack(simple_buf, 128, 50);
+
+    EXPECT_EQ(78, offset);
+
+    // 4 bytes header + 4 bytes content
+    EXPECT_EQ("2001:db8:1::dead:beef", opt->getAddress().toText());
+    EXPECT_EQ(1000, opt->getPreferred());
+    EXPECT_EQ(3000000000U, opt->getValid());
+
+    EXPECT_EQ(D6O_IAADDR, opt->getType());
+
+    EXPECT_EQ(Option::OPTION6_HDR_LEN + Option6IAAddr::OPTION6_IAADDR_LEN,
+              opt->len());
+
+    // check if pack worked properly:
+    // if option type is correct
+    EXPECT_EQ(D6O_IAADDR, simple_buf[50]*256 + simple_buf[51]);
+
+    // if option length is correct
+    EXPECT_EQ(24, simple_buf[52]*256 + simple_buf[53]);
+
+    // if option content is correct
+    EXPECT_EQ(0, memcmp(&simple_buf[0], &simple_buf[54],24));
+
+    EXPECT_NO_THROW(
+        delete opt;
+    );
+}
+
+}
diff --git a/src/lib/dhcp/tests/option_unittest.cc b/src/lib/dhcp/tests/option_unittest.cc
new file mode 100644
index 0000000..296022a
--- /dev/null
+++ b/src/lib/dhcp/tests/option_unittest.cc
@@ -0,0 +1,279 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+#include <iostream>
+#include <sstream>
+
+#include <arpa/inet.h>
+#include <gtest/gtest.h>
+#include <boost/shared_ptr.hpp>
+
+#include "dhcp/dhcp6.h"
+#include "dhcp/option.h"
+
+using namespace std;
+using namespace isc;
+using namespace isc::dhcp;
+
+namespace {
+class OptionTest : public ::testing::Test {
+public:
+    OptionTest() {
+    }
+};
+
+// v4 is not really implemented yet. A simple test will do for now
+TEST_F(OptionTest, basic4) {
+
+    Option* opt = new Option(Option::V4, 17);
+
+    EXPECT_EQ(17, opt->getType());
+    EXPECT_EQ(NULL, opt->getData());
+    EXPECT_EQ(2, opt->len()); // just v4 header
+
+    EXPECT_NO_THROW(
+        delete opt;
+    );
+}
+
+// tests simple constructor
+TEST_F(OptionTest, basic6) {
+
+    Option* opt = new Option(Option::V6, 1);
+
+    EXPECT_EQ(1, opt->getType());
+    EXPECT_EQ(NULL, opt->getData());
+    EXPECT_EQ(4, opt->len()); // just v6 header
+
+    EXPECT_NO_THROW(
+        delete opt;
+    );
+}
+
+// tests contructor used in pkt reception
+// option contains actual data
+TEST_F(OptionTest, data1) {
+    boost::shared_array<uint8_t> buf(new uint8_t[32]);
+    for (int i = 0; i < 32; i++)
+        buf[i] = 100+i;
+    Option* opt = new Option(Option::V6, 333, //type
+                             buf,
+                             3, // offset
+                             7); // 7 bytes of data
+    EXPECT_EQ(333, opt->getType());
+    ASSERT_EQ(&buf[3], opt->getData());
+    ASSERT_EQ(11, opt->len());
+    EXPECT_EQ(0, memcmp(&buf[3], opt->getData(), 7) );
+
+    int offset = opt->pack(buf, 32, 20);
+    EXPECT_EQ(31, offset);
+
+    EXPECT_EQ(buf[20], 333/256); // type
+    EXPECT_EQ(buf[21], 333%256);
+
+    EXPECT_EQ(buf[22], 0); // len
+    EXPECT_EQ(buf[23], 7);
+
+    // payload
+    EXPECT_EQ(0, memcmp(&buf[3], &buf[24], 7) );
+
+    EXPECT_NO_THROW(
+        delete opt;
+    );
+}
+
+// another text that tests the same thing, just
+// with different input parameters
+TEST_F(OptionTest, data2) {
+
+    boost::shared_array<uint8_t> simple_buf(new uint8_t[128]);
+    for (int i = 0; i < 128; i++)
+        simple_buf[i] = 0;
+    simple_buf[0] = 0xa1;
+    simple_buf[1] = 0xa2;
+    simple_buf[2] = 0xa3;
+    simple_buf[3] = 0xa4;
+
+    // create an option (unpack content)
+    Option* opt = new Option(Option::V6,
+                             D6O_CLIENTID,
+                             simple_buf,
+                             0,
+                             4);
+
+    // pack this option again in the same buffer, but in
+    // different place
+    int offset18 = opt->pack(simple_buf, 128, 10);
+
+    // 4 bytes header + 4 bytes content
+    EXPECT_EQ(8, opt->len());
+    EXPECT_EQ(D6O_CLIENTID, opt->getType());
+
+    EXPECT_EQ(offset18, 18);
+
+    // check if pack worked properly:
+    // if option type is correct
+    EXPECT_EQ(D6O_CLIENTID, simple_buf[10]*256 + simple_buf[11]);
+
+    // if option length is correct
+    EXPECT_EQ(4, simple_buf[12]*256 + simple_buf[13]);
+
+    // if option content is correct
+    EXPECT_EQ(0, memcmp(&simple_buf[0], &simple_buf[14],4));
+
+    EXPECT_NO_THROW(
+        delete opt;
+    );
+}
+
+// check that an option can contain 2 suboptions:
+// opt1
+//  +----opt2
+//  |
+//  +----opt3
+//
+TEST_F(OptionTest, suboptions1) {
+    boost::shared_array<uint8_t> buf(new uint8_t[128]);
+    for (int i=0; i<128; i++)
+        buf[i] = 100+i;
+    Option* opt1 = new Option(Option::V6, 65535, //type
+                              buf,
+                              0, // offset
+                              3); // 3 bytes of data
+    boost::shared_ptr<Option> opt2(new Option(Option::V6, 13));
+    boost::shared_ptr<Option> opt3(new Option(Option::V6, 7,
+                                              buf,
+                                              3, // offset
+                                              5)); // 5 bytes of data
+    opt1->addOption(opt2);
+    opt1->addOption(opt3);
+    // opt2 len = 4 (just header)
+    // opt3 len = 9 4(header)+5(data)
+    // opt1 len = 7 + suboptions() = 7 + 4 + 9 = 20
+
+    EXPECT_EQ(4, opt2->len());
+    EXPECT_EQ(9, opt3->len());
+    EXPECT_EQ(20, opt1->len());
+
+    uint8_t expected[] = {
+        0xff, 0xff, 0, 16, 100, 101, 102,
+        0, 7, 0, 5, 103, 104, 105, 106, 107,
+        0, 13, 0, 0 // no data at all
+    };
+
+    int offset = opt1->pack(buf, 128, 20);
+    EXPECT_EQ(40, offset);
+
+    // payload
+    EXPECT_EQ(0, memcmp(&buf[20], expected, 20) );
+
+    EXPECT_NO_THROW(
+        delete opt1;
+    );
+}
+
+// check that an option can contain 2 suboptions:
+// opt1
+//  +----opt2
+//        |
+//        +----opt3
+//
+TEST_F(OptionTest, suboptions2) {
+    boost::shared_array<uint8_t> buf(new uint8_t[128]);
+    for (int i=0; i<128; i++)
+        buf[i] = 100+i;
+    Option* opt1 = new Option(Option::V6, 65535, //type
+                              buf,
+                              0, // offset
+                              3); // 3 bytes of data
+    boost::shared_ptr<Option> opt2(new Option(Option::V6, 13));
+    boost::shared_ptr<Option> opt3(new Option(Option::V6, 7,
+                                              buf,
+                                              3, // offset
+                                              5)); // 5 bytes of data
+    opt1->addOption(opt2);
+    opt2->addOption(opt3);
+    // opt3 len = 9 4(header)+5(data)
+    // opt2 len = 4 (just header) + len(opt3)
+    // opt1 len = 7 + len(opt2)
+
+    uint8_t expected[] = {
+        0xff, 0xff, 0, 16, 100, 101, 102,
+        0, 13, 0, 9,
+        0, 7, 0, 5, 103, 104, 105, 106, 107,
+    };
+
+    int offset = opt1->pack(buf, 128, 20);
+    EXPECT_EQ(40, offset);
+
+    // payload
+    EXPECT_EQ(0, memcmp(&buf[20], expected, 20) );
+
+    EXPECT_NO_THROW(
+        delete opt1;
+    );
+}
+
+TEST_F(OptionTest, addgetdel) {
+    boost::shared_array<uint8_t> buf(new uint8_t[128]);
+    for (int i=0; i<128; i++)
+        buf[i] = 100+i;
+    Option* parent = new Option(Option::V6, 65535); //type
+    boost::shared_ptr<Option> opt1(new Option(Option::V6, 1));
+    boost::shared_ptr<Option> opt2(new Option(Option::V6, 2));
+    boost::shared_ptr<Option> opt3(new Option(Option::V6, 2));
+
+    parent->addOption(opt1);
+    parent->addOption(opt2);
+
+    // getOption() test
+    EXPECT_EQ(opt1, parent->getOption(1));
+    EXPECT_EQ(opt2, parent->getOption(2));
+
+    // expect NULL
+    EXPECT_EQ(boost::shared_ptr<Option>(), parent->getOption(4));
+
+    // now there are 2 options of type 2
+    parent->addOption(opt3);
+
+    // let's delete one of them
+    EXPECT_EQ(true, parent->delOption(2));
+
+    // there still should be the other option 2
+    EXPECT_NE(boost::shared_ptr<Option>(), parent->getOption(2));
+
+    // let's delete the other option 2
+    EXPECT_EQ(true, parent->delOption(2));
+
+    // no more options with type=2
+    EXPECT_EQ(boost::shared_ptr<Option>(), parent->getOption(2));
+
+    // let's try to delete - should fail
+    EXPECT_TRUE(false ==  parent->delOption(2));
+}
+
+}
+
+TEST_F(OptionTest, toText) {
+    boost::shared_array<uint8_t> buf(new uint8_t[3]);
+    buf[0] = 0;
+    buf[1] = 0xf;
+    buf[2] = 0xff;
+
+    boost::shared_ptr<Option> opt(new Option(Option::V6, 258,
+                                             buf, 0, 3));
+
+    EXPECT_EQ("type=258, len=3: 00:0f:ff", opt->toText());
+}
diff --git a/src/lib/dhcp/tests/pkt6_unittest.cc b/src/lib/dhcp/tests/pkt6_unittest.cc
new file mode 100644
index 0000000..2819f7d
--- /dev/null
+++ b/src/lib/dhcp/tests/pkt6_unittest.cc
@@ -0,0 +1,206 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+#include <iostream>
+#include <sstream>
+#include <arpa/inet.h>
+#include <gtest/gtest.h>
+
+#include "io_address.h"
+#include "dhcp/option.h"
+#include "dhcp/pkt6.h"
+#include "dhcp/dhcp6.h"
+
+using namespace std;
+using namespace isc;
+using namespace isc::asiolink;
+using namespace isc::dhcp;
+
+namespace {
+// empty class for now, but may be extended once Addr6 becomes bigger
+class Pkt6Test : public ::testing::Test {
+public:
+    Pkt6Test() {
+    }
+};
+
+TEST_F(Pkt6Test, constructor) {
+    Pkt6 * pkt1 = new Pkt6(17);
+
+    EXPECT_EQ(pkt1->data_len_, 17);
+
+    delete pkt1;
+}
+
+// captured actual SOLICIT packet: transid=0x3d79fb
+// options: client-id, in_na, dns-server, elapsed-time, option-request
+// this code is autogenerated (see src/bin/dhcp6/tests/iface_mgr_unittest.c)
+Pkt6 *capture1() {
+    Pkt6* pkt;
+    pkt = new Pkt6(98);
+    pkt->remote_port_ = 546;
+    pkt->remote_addr_ = IOAddress("fe80::21e:8cff:fe9b:7349");
+    pkt->local_port_ = 0;
+    pkt->local_addr_ = IOAddress("ff02::1:2");
+    pkt->ifindex_ = 2;
+    pkt->iface_ = "eth0";
+    pkt->data_[0]=1;
+    pkt->data_[1]=01;     pkt->data_[2]=02;     pkt->data_[3]=03;     pkt->data_[4]=0;
+    pkt->data_[5]=1;     pkt->data_[6]=0;     pkt->data_[7]=14;     pkt->data_[8]=0;
+    pkt->data_[9]=1;     pkt->data_[10]=0;     pkt->data_[11]=1;     pkt->data_[12]=21;
+    pkt->data_[13]=158;     pkt->data_[14]=60;     pkt->data_[15]=22;     pkt->data_[16]=0;
+    pkt->data_[17]=30;     pkt->data_[18]=140;     pkt->data_[19]=155;     pkt->data_[20]=115;
+    pkt->data_[21]=73;     pkt->data_[22]=0;     pkt->data_[23]=3;     pkt->data_[24]=0;
+    pkt->data_[25]=40;     pkt->data_[26]=0;     pkt->data_[27]=0;     pkt->data_[28]=0;
+    pkt->data_[29]=1;     pkt->data_[30]=255;     pkt->data_[31]=255;     pkt->data_[32]=255;
+    pkt->data_[33]=255;     pkt->data_[34]=255;     pkt->data_[35]=255;     pkt->data_[36]=255;
+    pkt->data_[37]=255;     pkt->data_[38]=0;     pkt->data_[39]=5;     pkt->data_[40]=0;
+    pkt->data_[41]=24;     pkt->data_[42]=32;     pkt->data_[43]=1;     pkt->data_[44]=13;
+    pkt->data_[45]=184;     pkt->data_[46]=0;     pkt->data_[47]=1;     pkt->data_[48]=0;
+    pkt->data_[49]=0;     pkt->data_[50]=0;     pkt->data_[51]=0;     pkt->data_[52]=0;
+    pkt->data_[53]=0;     pkt->data_[54]=0;     pkt->data_[55]=0;     pkt->data_[56]=18;
+    pkt->data_[57]=52;     pkt->data_[58]=255;     pkt->data_[59]=255;     pkt->data_[60]=255;
+    pkt->data_[61]=255;     pkt->data_[62]=255;     pkt->data_[63]=255;     pkt->data_[64]=255;
+    pkt->data_[65]=255;     pkt->data_[66]=0;     pkt->data_[67]=23;     pkt->data_[68]=0;
+    pkt->data_[69]=16;     pkt->data_[70]=32;     pkt->data_[71]=1;     pkt->data_[72]=13;
+    pkt->data_[73]=184;     pkt->data_[74]=0;     pkt->data_[75]=1;     pkt->data_[76]=0;
+    pkt->data_[77]=0;     pkt->data_[78]=0;     pkt->data_[79]=0;     pkt->data_[80]=0;
+    pkt->data_[81]=0;     pkt->data_[82]=0;     pkt->data_[83]=0;     pkt->data_[84]=221;
+    pkt->data_[85]=221;     pkt->data_[86]=0;     pkt->data_[87]=8;     pkt->data_[88]=0;
+    pkt->data_[89]=2;     pkt->data_[90]=0;     pkt->data_[91]=100;     pkt->data_[92]=0;
+    pkt->data_[93]=6;     pkt->data_[94]=0;     pkt->data_[95]=2;     pkt->data_[96]=0;
+    pkt->data_[97]=23;
+    return (pkt);
+}
+
+TEST_F(Pkt6Test, unpack_solicit1) {
+    Pkt6 * sol = capture1();
+
+    ASSERT_EQ(true, sol->unpack());
+
+    // check for length
+    EXPECT_EQ(98, sol->len() );
+
+    // check for type
+    EXPECT_EQ(DHCPV6_SOLICIT, sol->getType() );
+
+    // check that all present options are returned
+    EXPECT_TRUE(sol->getOption(D6O_CLIENTID)); // client-id is present
+    EXPECT_TRUE(sol->getOption(D6O_IA_NA));    // IA_NA is present
+    EXPECT_TRUE(sol->getOption(D6O_ELAPSED_TIME));  // elapsed is present
+    EXPECT_TRUE(sol->getOption(D6O_NAME_SERVERS));
+    EXPECT_TRUE(sol->getOption(D6O_ORO));
+
+    // let's check that non-present options are not returned
+    EXPECT_FALSE(sol->getOption(D6O_SERVERID)); // server-id is missing
+    EXPECT_FALSE(sol->getOption(D6O_IA_TA));
+    EXPECT_FALSE(sol->getOption(D6O_IAADDR));
+
+    std::cout << sol->toText();
+
+    delete sol;
+}
+
+TEST_F(Pkt6Test, packUnpack) {
+
+    Pkt6 * parent = new Pkt6(100);
+
+    parent->setType(DHCPV6_SOLICIT);
+
+    boost::shared_ptr<Option> opt1(new Option(Option::V6, 1));
+    boost::shared_ptr<Option> opt2(new Option(Option::V6, 2));
+    boost::shared_ptr<Option> opt3(new Option(Option::V6, 100));
+    // let's not use zero-length option type 3 as it is IA_NA
+
+    parent->addOption(opt1);
+    parent->addOption(opt2);
+    parent->addOption(opt3);
+
+    EXPECT_EQ(DHCPV6_SOLICIT, parent->getType());
+    int transid = parent->getTransid();
+    // transaction-id was randomized, let's remember it
+
+    // calculated length should be 16
+    EXPECT_EQ( Pkt6::DHCPV6_PKT_HDR_LEN + 3*Option::OPTION6_HDR_LEN, 
+               parent->len() );
+
+    EXPECT_TRUE( parent->pack() );
+
+    //
+    EXPECT_EQ( Pkt6::DHCPV6_PKT_HDR_LEN + 3*Option::OPTION6_HDR_LEN, 
+               parent->len() );
+
+    // let's delete options from options_ collection
+    // they still be defined in packed 
+    parent->options_.clear();
+
+    // that that removed options are indeed are gone
+    EXPECT_EQ( 4, parent->len() );
+
+    // now recreate options list
+    EXPECT_TRUE( parent->unpack() );
+
+    // transid, message-type should be the same as before
+    EXPECT_EQ(transid, parent->getTransid());
+    EXPECT_EQ(DHCPV6_SOLICIT, parent->getType());
+    
+    EXPECT_TRUE( parent->getOption(1));
+    EXPECT_TRUE( parent->getOption(2));
+    EXPECT_TRUE( parent->getOption(100));
+    EXPECT_FALSE( parent->getOption(4));
+    
+    delete parent;
+}
+
+TEST_F(Pkt6Test, addGetDelOptions) {
+    Pkt6 * parent = new Pkt6(100);
+
+    boost::shared_ptr<Option> opt1(new Option(Option::V6, 1));
+    boost::shared_ptr<Option> opt2(new Option(Option::V6, 2));
+    boost::shared_ptr<Option> opt3(new Option(Option::V6, 2));
+
+    parent->addOption(opt1);
+    parent->addOption(opt2);
+
+    // getOption() test
+    EXPECT_EQ(opt1, parent->getOption(1));
+    EXPECT_EQ(opt2, parent->getOption(2));
+
+    // expect NULL
+    EXPECT_EQ(boost::shared_ptr<Option>(), parent->getOption(4));
+
+    // now there are 2 options of type 2
+    parent->addOption(opt3);
+
+    // let's delete one of them
+    EXPECT_EQ(true, parent->delOption(2));
+
+    // there still should be the other option 2
+    EXPECT_NE(boost::shared_ptr<Option>(), parent->getOption(2));
+
+    // let's delete the other option 2
+    EXPECT_EQ(true, parent->delOption(2));
+
+    // no more options with type=2
+    EXPECT_EQ(boost::shared_ptr<Option>(), parent->getOption(2));
+
+    // let's try to delete - should fail
+    EXPECT_TRUE(false ==  parent->delOption(2));
+
+    delete parent;
+}
+
+
+}
diff --git a/src/lib/dhcp/tests/run_unittests.cc b/src/lib/dhcp/tests/run_unittests.cc
new file mode 100644
index 0000000..db27f76
--- /dev/null
+++ b/src/lib/dhcp/tests/run_unittests.cc
@@ -0,0 +1,27 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <gtest/gtest.h>
+
+#include <log/logger_support.h>
+
+int
+main(int argc, char* argv[]) {
+    ::testing::InitGoogleTest(&argc, argv);
+    isc::log::initLogger();
+
+    int result = RUN_ALL_TESTS();
+
+    return (result);
+}
diff --git a/src/lib/dns/tests/Makefile.am b/src/lib/dns/tests/Makefile.am
index e4c577e..ceeb3b8 100644
--- a/src/lib/dns/tests/Makefile.am
+++ b/src/lib/dns/tests/Makefile.am
@@ -73,4 +73,4 @@ run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.
 run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 endif
 
-check_PROGRAMS = $(TESTS)
+noinst_PROGRAMS = $(TESTS)
diff --git a/src/lib/exceptions/tests/Makefile.am b/src/lib/exceptions/tests/Makefile.am
index 35161a1..2444b02 100644
--- a/src/lib/exceptions/tests/Makefile.am
+++ b/src/lib/exceptions/tests/Makefile.am
@@ -20,4 +20,4 @@ run_unittests_LDADD = $(GTEST_LDADD)
 run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 endif
 
-check_PROGRAMS = $(TESTS)
+noinst_PROGRAMS = $(TESTS)
diff --git a/src/lib/log/tests/Makefile.am b/src/lib/log/tests/Makefile.am
index 8ca561d..a5f793c 100644
--- a/src/lib/log/tests/Makefile.am
+++ b/src/lib/log/tests/Makefile.am
@@ -45,7 +45,7 @@ run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
 endif
 
-check_PROGRAMS = logger_example
+noinst_PROGRAMS = logger_example
 logger_example_SOURCES = logger_example.cc
 logger_example_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 logger_example_LDFLAGS = $(AM_LDFLAGS) $(LOG4CPLUS_LDFLAGS)
@@ -53,7 +53,7 @@ logger_example_LDADD  = $(top_builddir)/src/lib/log/liblog.la
 logger_example_LDADD += $(top_builddir)/src/lib/util/libutil.la
 logger_example_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 
-check_PROGRAMS += init_logger_test
+noinst_PROGRAMS += init_logger_test
 init_logger_test_SOURCES = init_logger_test.cc
 init_logger_test_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 init_logger_test_LDFLAGS = $(AM_LDFLAGS) $(LOG4CPLUS_LDFLAGS)
@@ -61,7 +61,7 @@ init_logger_test_LDADD  = $(top_builddir)/src/lib/log/liblog.la
 init_logger_test_LDADD += $(top_builddir)/src/lib/util/libutil.la
 init_logger_test_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 
-check_PROGRAMS += $(TESTS)
+noinst_PROGRAMS += $(TESTS)
 
 # Additional test using the shell.  These are principally tests
 # where the global logging environment is affected, and where the
diff --git a/src/lib/nsas/tests/Makefile.am b/src/lib/nsas/tests/Makefile.am
index 8845187..420e897 100644
--- a/src/lib/nsas/tests/Makefile.am
+++ b/src/lib/nsas/tests/Makefile.am
@@ -60,4 +60,4 @@ run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.
 run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 endif
 
-check_PROGRAMS = $(TESTS)
+noinst_PROGRAMS = $(TESTS)
diff --git a/src/lib/resolve/tests/Makefile.am b/src/lib/resolve/tests/Makefile.am
index 7c42c36..cf05d9b 100644
--- a/src/lib/resolve/tests/Makefile.am
+++ b/src/lib/resolve/tests/Makefile.am
@@ -38,4 +38,4 @@ run_unittests_LDADD +=  $(top_builddir)/src/lib/exceptions/libexceptions.la
 
 endif
 
-check_PROGRAMS = $(TESTS)
+noinst_PROGRAMS = $(TESTS)
diff --git a/src/lib/server_common/tests/Makefile.am b/src/lib/server_common/tests/Makefile.am
index d07be52..d7e113a 100644
--- a/src/lib/server_common/tests/Makefile.am
+++ b/src/lib/server_common/tests/Makefile.am
@@ -49,6 +49,6 @@ run_unittests_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
 run_unittests_LDADD += $(top_builddir)/src/lib/config/tests/libfake_session.la
 endif
 
-check_PROGRAMS = $(TESTS)
+noinst_PROGRAMS = $(TESTS)
 
 EXTRA_DIST = testdata/spec.spec
diff --git a/src/lib/testutils/Makefile.am b/src/lib/testutils/Makefile.am
index ae5c6da..a511d24 100644
--- a/src/lib/testutils/Makefile.am
+++ b/src/lib/testutils/Makefile.am
@@ -5,7 +5,7 @@ AM_CPPFLAGS += $(BOOST_INCLUDES)
 AM_CXXFLAGS=$(B10_CXXFLAGS)
 
 if HAVE_GTEST
-lib_LTLIBRARIES = libtestutils.la
+noinst_LTLIBRARIES = libtestutils.la
 
 libtestutils_la_SOURCES = srv_test.h srv_test.cc
 libtestutils_la_SOURCES += dnsmessage_test.h dnsmessage_test.cc
diff --git a/src/lib/util/pyunittests/Makefile.am b/src/lib/util/pyunittests/Makefile.am
index 02fb8c2..dd2d39a 100644
--- a/src/lib/util/pyunittests/Makefile.am
+++ b/src/lib/util/pyunittests/Makefile.am
@@ -2,7 +2,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += $(BOOST_INCLUDES)
 AM_CXXFLAGS = $(B10_CXXFLAGS)
 
-check_LTLIBRARIES = pyunittests_util.la
+noinst_LTLIBRARIES = pyunittests_util.la
 
 pyunittests_util_la_SOURCES = pyunittests_util.cc
 pyunittests_util_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES)
diff --git a/src/lib/util/tests/Makefile.am b/src/lib/util/tests/Makefile.am
index b61804e..47243f8 100644
--- a/src/lib/util/tests/Makefile.am
+++ b/src/lib/util/tests/Makefile.am
@@ -40,4 +40,4 @@ run_unittests_LDADD += \
 run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 endif
 
-check_PROGRAMS = $(TESTS)
+noinst_PROGRAMS = $(TESTS)
diff --git a/src/lib/util/unittests/Makefile.am b/src/lib/util/unittests/Makefile.am
index 8006262..bbb0d49 100644
--- a/src/lib/util/unittests/Makefile.am
+++ b/src/lib/util/unittests/Makefile.am
@@ -1,7 +1,7 @@
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CXXFLAGS = $(B10_CXXFLAGS)
 
-check_LTLIBRARIES = libutil_unittests.la
+noinst_LTLIBRARIES = libutil_unittests.la
 libutil_unittests_la_SOURCES = fork.h fork.cc resolver.h
 libutil_unittests_la_SOURCES += newhook.h newhook.cc
 libutil_unittests_la_SOURCES += testdata.h testdata.cc
diff --git a/tests/tools/badpacket/Makefile.am b/tests/tools/badpacket/Makefile.am
index 61b76b2..fcba404 100644
--- a/tests/tools/badpacket/Makefile.am
+++ b/tests/tools/badpacket/Makefile.am
@@ -12,7 +12,7 @@ endif
 
 CLEANFILES = *.gcno *.gcda
 
-check_PROGRAMS  = badpacket
+noinst_PROGRAMS  = badpacket
 badpacket_SOURCES  = badpacket.cc
 badpacket_SOURCES += command_options.cc command_options.h
 badpacket_SOURCES += header_flags.h
diff --git a/tests/tools/badpacket/tests/Makefile.am b/tests/tools/badpacket/tests/Makefile.am
index a110e11..2daa664 100644
--- a/tests/tools/badpacket/tests/Makefile.am
+++ b/tests/tools/badpacket/tests/Makefile.am
@@ -29,4 +29,4 @@ run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
 endif
 
-check_PROGRAMS = $(TESTS)
+noinst_PROGRAMS = $(TESTS)




More information about the bind10-changes mailing list