OpenSolaris_b135/lib/libdhcputil/README.inittab

#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License, Version 1.0 only
# (the "License").  You may not use this file except in compliance
# with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
Copyright (c) 2001 by Sun Microsystems, Inc.
All rights reserved.

Inittab Purpose, Goals, and Functionality
Peter Memishian
ident	"%Z%%M%	%I%	%E% SMI"

PROBLEM STATEMENT
=================

Currently, each DHCP-related utility that needs to handle DHCP options
uses ad-hoc methods for learning and using them, ranging from using
hard-coded internal tables to providing published (but distinct)
configuration files describing these options.

Originally, when only the DHCP server needed to be concerned with DHCP
options, not having a standard API for managing and parsing DHCP
options was understandable.  Now, with four consumers of DHCP options
in core Solaris (in.dhcpd, dhcpinfo, snoop, and dhcpmgr), the
situation has spiraled out of control.  In addition to the obvious
maintenance headache caused by the redundant code, it has also become
a burden to our customers, who already have to cope with multiple
places where DHCP option information is stored (dhcptags(4),
dhcptab(4)).

The inittab API is designed to reduce the confusion, both for the
customer and the application developer.  Its goal is to provide a
single configuration for applications to receive their DHCP option
knowledge from and general routines for encoding and decoding DHCP
options.

INITTAB
=======

The inittab file contains information regarding the syntax and (to
some degree) the semantics of DHCP options.  It is primarily a
read-only file (like /etc/termcap) and should not need to be changed
by users.  Experienced sysadmins may need to update this file to add
new DHCP options, but this should be rare.

The inittab file consists of inittab records, each being one line long
and describing a particular option.  The format is based heavily on
the format for defining symbols in dhcptab(4).  Each line has the
following syntax:

   option_name	category, code, type, granularity, maximum, consumers

where:

   `option_name' is user-interpretable name of the option (for use with
      dhcpinfo(1M) for instance).  This field should at least be per-
      category unique and ideally should be unique across all categories.
      Of particular note is that options names in the STANDARD, SITE, and
      VENDOR spaces should not overlap, or the behavior is undefined.

   `category' is one of STANDARD, SITE, VENDOR, FIELD, or INTERNAL and
      identifies the namespace in which the option falls.

   `code' is the code of this option when it is sent over the
      wire.  (note: in most cases, `code' uniquely identifies the
      option, without a category.  however, in the case of internal
      categories like FIELD or INTERNAL, `code' may be used for
      other purposes and thus may not be globally unique).  This field
      should be per-category unique and the STANDARD and SITE fields
      should not have overlapping code fields or the behavior is
      undefined.

   `type' describes the payload associated with this option.  Valid
      types are IP, ASCII, OCTET, NUMBER, BOOL, UNUMBER8, UNUMBER16,
      UNUMBER32, SNUMBER8, SNUMBER16, and SNUMBER32.  For numbers,
      a preceding `U' or `S' indicates whether the number is unsigned
      or signed, and the trailing number indicates the number of bits
      in the number.

   `granularity' describes how many units of `type' payload make
      up a whole value for this option.  In the case of `NUMBER',
      granularity describes the number of bytes in the number.  Note
      that `NUMBER' is preserved for compatibility, but the more
      descriptive [SU]NUMBER{8,16,32,64} types should preferred.

   `maximum' describes how many whole values are allowed for this
      option.  0 indicates an infinite number.

   `consumers' describe which programs make use of this information.
      (`i' for dhcpinfo, `s' for snoop, `d' for in.dhcpd, and
       `m' for dhcpmgr).

A sample entry would be

  StaticRt	STANDARD, 33, IP, 2, 0, isdm

which describes an option named `StaticRt', that is in the STANDARD
category (i.e., defined by the DHCP standard), and is option code
33, which is of type `IP Address', consisting of a potentially
infinite number of pairs of IP addresses.  Lastly, the consumers of
option are dhcpinfo, snoop, in.dhcpd and dhcpmgr.

Comments in the inittab file begin with `#', and end with a newline.
Comments need not start at the beginning of a line.  Lines cannot be
continued (with `\' for instance).

The inittab file becomes the authoritative source for all DHCP options 
for all DHCP option consumers, with the following exceptions and notes:

   o  The DHCP agent and DHCP server both have their core protocol-
      related functionality hardcoded into them, so changes to the
      inittab file do not generally affect their inner workings.

   o  A program can specify which entries it wants from the inittab.
      This means that some DHCP options will never be used by some
      programs, even if they are listed as a `consumer' of the given
      option.  An example of this is that the DHCP server never
      requests any fields with the VENDOR category. (VENDOR information
      for the DHCP server comes from dhcptab(4) instead).

   o  In general, changing provided information in a released inittab
      file is ill-advised.  Adding new entries should be the extent
      of the modifications that are performed.

   o  The inittab C API also provides functions which allow programs
      to verify that a given entry in the inittab file is correct
      (which it does by consulting a compiled-in database of current
      options).  In general, this functionality is only used where
      absolutely necessary, since it nullifies some of the advantages
      of having an inittab.

   o  Where a symbol is defined both in the inittab and in dhcptab(4),
      inittab is authoritative.  EXTEND symbol definitions in
      dhcptab(4) will be deprecated in a future release of Solaris.

C-LEVEL API
===========

Each inittab entry describes a specific DHCP option and is defined as
a dhcp_symbol_t (as defined in usr/src/lib/libdhcputil/common/dhcp_symbol.h).

In general, it is expected that inittab entries are acquired via
inittab_load(), inittab_getbyname(), or inittab_getbycode() and passed
as needed to the remaining inittab_XXX functions.  If consumers need
to convert the inittab entries into a different format, then the
fields inside the inittab entry may be read directly.  Some inittab
functions return dynamically allocated parameters; all such parameters
can be freed with free(3c).

To get an inittab entry, one of the following API's must be used:

    dhcp_symbol_t *
    inittab_load(uchar_t categories, char consumer, size_t *n_entries);
    
    dhcp_symbol_t *
    inittab_getbyname(uchar_t categories, char consumer, const char *name);
    
    dhcp_symbol_t *
    inittab_getbycode(uchar_t categories, char consumer, unsigned int code);

where the `categories' parameter consists of the following values OR'd
together:

    #define ITAB_CAT_STANDARD	0x01
    #define ITAB_CAT_FIELD	0x02
    #define ITAB_CAT_INTERNAL	0x04
    #define ITAB_CAT_VENDOR	0x08
    #define ITAB_CAT_SITE	0x10

and the `consumer' field consists of one of the following:

    #define ITAB_CONS_INFO	'i'
    #define ITAB_CONS_SERVER	'd'
    #define ITAB_CONS_SNOOP	's'
    #define ITAB_CONS_MANAGER	'm'

inittab_load() creates and returns an array of dhcp_symbol_t's made
up of all the entries of the specified categories that are available
to the provided consumer.  Note that there is no specified order to
the entries returned.  The array is dynamically allocated, and the
number of items in the array is returned in the `n_entries' parameter.

inittab_getbyname()/inittab_getbycode() return an dhcp_symbol_t
matching the given name or code for the provided category and the
provided consumer.  The dhcp_symbol_t is dynamically allocated.

Some inittab consumers may need to make sure that a given inittab
entry has not been corrupted in the inittab file.  For those cases,
inittab_verify() can be used to validate an inittab_entry against an
internal table compiled into the inittab API:

    int
    inittab_verify(dhcp_symbol_t *inittab_ent,
		   dhcp_symbol_t *internal_ent);

where `inittab_ent' is an dhcp_symbol_t previously returned from
inittab_load() or inittab_getbyX().  inittab_verify() returns
ITAB_SUCCESS if `inittab_ent' is verified to be correct, ITAB_FAILURE
if `inittab_ent' is incorrect, and ITAB_UNKNOWN if inittab_verify()
doesn't know.  If `internal_ent' is non-NULL, it is filled in with the
value of the option known internally to the inittab API.  Entries are
verified using the `ds_category' and `ds_code' fields from the
dhcp_symbol_t.  For ITAB_SUCCESS to be returned, the entry passed in
and the internal entry both must have the same ds_gran, ds_max, and
ds_type values.

To perform encoding and decoding of DHCP options, the following
routines are provided:

    uchar_t *
    inittab_encode(dhcp_symbol_t *inittab_ent, const char *data,
		   uint16_t *lengthp, boolean_t just_payload);

    const char *
    inittab_decode(dhcp_symbol_t *inittab_ent, uchar_t *data,
		   uint16_t length, boolean_t just_payload);

Both of these routines take an `inittab_ent' that was previously
returned from inittab_load() or inittab_getbyX().

For inittab_encode(), `data' is an ASCII string to encode, and a
pointer to a dynamically allocated byte-array representing the encoded
option is returned.  The size of the resulting data returned is stored
in `lengthp'.  Note that if the `just_payload' option is set, then
only the payload of the option is returned (i.e., the option code and
option length is left off the returned data).  To encode multiple
items of a given type, separate the items by spaces, such as
"109.108.21.1 148.232.2.1".  Octal data should be of the form "0xNN"
where NN is a hexadecimal digit representing the byte.

For inittab_decode(), `data' is a byte-array representing an encoded
option, which is `length' bytes long.  A pointer to a dynamically
allocated string representing the option's value in ASCII is returned.
Note that if the `data' byte-array consists of just the payload of the
option, then the `just_payload' option should be set.

In addition, the following routines return extended error information
for reporting parsing errors:

    uchar_t *
    inittab_encode_e(dhcp_symbol_t *inittab_ent, const char *data,
		   uint16_t *lengthp, boolean_t just_payload, int *eerrno);

    const char *
    inittab_decode_e(dhcp_symbol_t *inittab_ent, uchar_t *data,
		   uint16_t length, boolean_t just_payload, int *eerrno);


The extended codes:

/*
 * DHCP Extended error codes
 */
#define ITAB_SYNTAX_ERROR       (-1)
#define ITAB_BAD_IPADDR         (-2)
#define ITAB_BAD_STRING         (-3)
#define ITAB_BAD_OCTET          (-4)
#define ITAB_BAD_NUMBER         (-5)
#define ITAB_BAD_BOOLEAN        (-6)
#define ITAB_NOT_ENOUGH_IP      (-7)
#define ITAB_BAD_GRAN           (-8)


ENVIRONMENT VARIABLES
=====================

In order to aid in debugging inittab-related problems, two environment
variables, DHCP_INITTAB_DEBUG, and DHCP_INITTAB_PATH, can be set
before starting a program which uses the inittab API.

If DHCP_INITTAB_DEBUG is an exported environment variable, then the
inittab API will print useful diagnostic messages handy in tracking
down problems in the inittab file.  If DHCP_INITTAB_PATH is an
exported environment variable, then its value is used as the location
of the inittab file, instead of /etc/dhcp/inittab.

--
Peter Memishian, Internet Engineering, Solaris Software (meem@east.sun.com)