===============================================================
    Red Hat DHCP D-BUS Daemon (dhcdbd)  
	
    Usage Guide

    Copyright (C) 2006 Red Hat, Inc.  All rights reserved.
    Red Hat Authors: Jason Vas Dias
                     David Cantrell
===============================================================
 
Purpose:
    dhcdbd exists to:
        o  provide D-BUS control of the ISC dhclient software,
        o  store DHCP configuration parameters (options) persistently
        o  providing access to DHCP options over D-BUS
        o  notify applications of changes to DHCP IP interface configuration

Usage:
    dhcdbd is designed to be started as a D-BUS service from a service
    description file, by default /usr/share/dbus-1/services/dhcdbd.service;
    hence the default bus it will connect to is the "STARTER" bus, and it
    must be installed setuid to root.

    It now also has an initscript, so "service dhcdbd start" will make dhcdbd
    connect to the SYSTEM bus, and dhcdbd need not be installed root setuid.

    dhcdbd accepts these command-line parameters, all of which are optional:

        (-s | -S | --system)                : use system bus
        (-u | -U | --session)               : use session bus
        (-n | -N | --no-daemon )            : stay in foreground 
        (-d | -D | --dest=)  <destination>  : set connection destination
                                                  default: 'com.redhat.dhcp'
        (-o | -O | --path=)  <path>         : set object path prefix
                                                  default: '/com/redhat/dhcp'
        (-i | -I | --prefix=)<prefix>       : set interface prefix
                                                  default: 'com.redhat.dhcp'

    NOTE:
        dhcdbd depends on dhclient-script extensions present in Red Hat
        dhclient versions 3.0.2-12 and above, and will not function without
        them.

D-BUS Names Served:

    Key:
    O: Object Path (-O suffix)
    M: Member
    I: Interface (-I suffix)
    P: Purpose

    O: /com/redhat/dhcp/
    M: $ip_if
    I: up
    P: Start dhclient session for $ip_if ($ip_if: IPv4 interface name).
       Accepts up to 2 optional uint32 arguments:
           arg 1: dhclient-script flags
           arg 2: dhclient flags (see below) 

    O: /com/redhat/dhcp/
    M: $ip_if
    I: down
    P: Stop dhclient session for $ip_if

    O: /com/redhat/dhcp/
    M: $ip_if or $ip_if/$option
    I: text.get
    P: Returns DHCP options for $ip_if/ or $ip_if/$option or single
       $ip_if/$option option as text strings.

    O: /com/redhat/dhcp/
    M: $ip_if or $ip_if/$option
    I: binary.get
    P: Returns DHCP options for $ip_if/ or $ip_if/$option or single
       $ip_if/$option option as "array of byte" D-BUS type corresponding
       to "C" structure.
	
    O: /com/redhat/dhcp/
    M: $ip_if
    I: dbus.get
    P: Returns DHCP options for $ip_if/ or $ip_if/$option or single
       $ip_if/$option option as binary D-BUS types.

    O: /com/redhat/dhcp/
    M: $ip_if/old.$option
    I: {text,dbus,binary}.get
    P: Returns options with "old" prefix (from previous, expired lease).

    O: /com/redhat/dhcp/$ip_if/
    M: $option
    I: {text,dbus}.format.get
    P: Returns DHCP option format for option:
           byte:   dhcp option code
           string: dhcp option type string
           byte:   dhcp universe code
           string: dhcp universe name
           string: proper dhcp option name
           byte:   1: is "NEW" user-defined option
                   0: is standard dhcp option
								
    O: /com/redhat/dhcp
    M: $ip_if
    I: state
    P: dhcdbd broadcasts STATE SIGNAL messages to the null destination on
       the system bus from the com.redhat.dhcp.state interface from member
       /com/redhat/dhcp/$ip_if so all processes can be informed of dhcp
       state changes.

    O: /com/redhat/dhcp/
    M: $ip_if
    I: subscribe.(binary|text|dbus) (string)       
    P: Subscription method taking one string option name argument.  dhcdbd
       will send signals to the 'subscribe' sender from the same interface
       for the $ip_if/$option member whenever it changes.  The subscriber
       is removed if its name is no longer valid.	

    O: /com/redhat/dhcp/
    M: subscribe.binary ($option)
       subscribe.text   "
       subscribe.dbus
    I:
    P: Prospective subscription: Subscribers can now omit the interface and
       will be sent option values from any interface.

    O: /com/redhat/dhcp
    M: list
    I:
    P: Return string list of configured interface names.
	
    O: /com/redhat/dhcp
    M: (up|ping)
    I:
    P: Just start up and do nothing.

    O: /com/redhat/dhcp
    M: (down|quit|exit|shutdown)
    I:
    P: Exit (Also exits automatically on Disconnected signal from
       /org/freedesktop/DBus/Local).

State Changes:
	
    The $path/$ip_if/reason option contains the "state" of the interface
    that is sent as a uint32 in D-BUS SIGNAL messages from the $path/$ip_if
    object $interface.state D-BUS interface when the DHCP configuration
    status of the $ip_if changes.

    When retrieved using the 'text.get' interface, a string value is
    returned which is an enumeration of the uint32 values sent in the
    signal as follows:

    String retrieved  uint32 sent
    by text.get:      in signal:    meaning:                    next states:
    ----------------- ------------- --------------------------- -------------
    "NBI"             0             no broadcast interfaces     END
                                    were found

    "PREINIT"         1             configuration started       BOUND, REBOOT,
                                                                REBIND
                                    no options valid            TIMEOUT, FAIL,
                                                                RELEASE, STOP

    "BOUND"           2             lease obtained, options     PREINIT
                                    valid

    "RENEW"           3             lease renewed by same       PREINIT
                                    session

    "REBOOT"          4             existing lease renewed      PREINIT
                                    by new session

    "REBIND"          5             new, different lease        PREINIT
                                    obtained after expiry

    "STOP"            6             unconfigure old lease,      PREINIT
                                    NO release

    "MEDIUM"          7             media selection begun       -
                                    (unsupported on Linux)

    "TIMEOUT"         8             timed out contacting        PREINIT
                                    DHCP server, revert to
                                    last active lease

    "FAIL"            9             all attempts to contact     PREINIT
                                    server timed out, sleeping
                                    no lease configured

    "EXPIRE"          10            lease expired, renewing     PREINIT	


    "RELEASE"         11            releasing lease             PREINIT, STOP


    "START"           12            dhclient started            PREINIT
                                    successfully

    "ABEND"           13            dhclient exited             PREINIT
                                    abnormally

    "END"             14            dhclient exited             PREINIT
                                    normally

The $ip_if/ up method:

    The "up" method accepts one or two optional uint32 arguments:
        uint32 mode: this is a bit set of 5 bits that control what actions
                     will be performed by the dhclient-script:

            0: (default) the script runs as normal, just sending all the
               DHCP options to dhcdbd

            1: turns off modification of resolv.conf

            2: turns off all ifconfig actions

            4: turns off all route modification actions

            8: turns off configuration of yp server

            16: turns off configuration of ntp server
		
            31: turns off ALL actions and dhclient-script just writes
                options to dhcdbd

	
        uint32 down_flags: this is a bit set of 2 bits that control how
                           the dhclient process will be started up or shut
                           down.
		
            0: dhclient is run in ONE SHOT mode (will give up after one
               iteration of DHCPDISCOVER algorithm after all attempts to
               contact server have failed.
				
            1: dhclient is run in PERSISTANT mode: if attempts to contact
               DHCP server fails, dhclient sleeps for a configurable
               interval and retries.

            2: dhclient is to release the lease when shut down (it will
               send the DHCPRELEASE packet).

            4: Remove the dhclient-${IF}.leases file before starting dhclient

    NOTE:  By default, dhclient attempts to access its configuration file
    /etc/dhclient.conf.  If the per-interface ($IF) /etc/dhclient-${IF}.conf
    file exists, dhcdbd will invoke dhclient with the
    "-cf /etc/dhclient-${IF}.conf" argument to use that file instead.
 
Subscriptions:

    Subscribers can invoke the "subscribe" method on an interface.  Eg, to
    subscribe to changes of the
        binary "ip-address" option on the eth0 interface:
            Subscriber sends "method_call" message:
                path:       /com/redhat/dhcp/eth0
                interface:  com.redhat.dhcp.subscribe
                member:     binary
                arguments:  string:'ip-address'
            dhcdbd sends RETURN message with uint32:0 argument if
            subscription succeeds, or an ERROR message if it doesn't.
	
    Henceforth, until the org.freedesktop.DBus.NameHasOwner method returns
    false for the subscriber's destination, whenever a new value of
    ip-address for eth0 is created, dhcdbd will send a subscribe signal to
    the subscriber's destination:
         destination: subscriber - "sender" of subscribe message
             path:       /com/redhat/dhcp/eth0
             member:     ip_address
             interface:  com.redhat.dhcp.subscribe.binary
             arguments:  name: STRING "ip-address"
                         value: ARRAY BYTE length=4 [ B B B B ]

    dhcdbd will always send the state signal as described above, and send
    any subscribe signals for the "reason" option, before sending subscribe
    signals for any other option. 
	
    Once signals for all subscribed options have been sent to a subsciber,
    dhcdbd will send a "reason" of 15 (DHCLIENT_END_OPTIONS) signifying
    that no more subscribed options are to be sent for the dhclient set
    session.

Prospective Subscriptions:

    Subscribers can send "subscribe" messages to dhcdbd without an interface
    path suffix, even before dhcdbd has brought any interfaces up; they will
    then receive subscription signals for any subsequent interface that is
    brought up, from the path suffixed by the interface name.
		
    See tests/test_binary_subscriber.c and tests/test_prospective_subscriber.c
    for details .
							       	
Examples:
	
    Here are some examples using dbus-send to contact dhcdbd:

    /usr/bin/dbus-send --dest=com.redhat.dhcp --type=method_call \
                       --print-reply --reply-timeout=20000 \
                       /com/redhat/dhcp/eth0 \
                       com.redhat.dhcp.up uint32:7 uint32:2
	
    Brings up interface eth0, telling dhclient-script not to modify
    resolv.conf, perform ifconfigs, or modify routes, but TO configure
    ntp.conf, ntp/step-tickers and yp.conf.  When this interface is brought
    down, the lease is to be released.

    Subsequent "up"s without "down"s invoke the "down" automatically
    followed by the "up".

        $ /usr/bin/dbus-send --system --dest=com.redhat.dhcp \
                             --type=method_call --print-reply \
                             --reply-timeout=20000 /com/redhat/dhcp/eth0 \
                             com.redhat.dhcp.text.get.ip_address
        method return sender=:1.3 -> dest=:1.7	
        1 string "172.16.80.119"

        $ /usr/bin/dbus-send --system --dest=com.redhat.dhcp \
                             --type=method_call --print-reply \ 
                             --reply-timeout=20000 /com/redhat/dhcp/eth0 \
                             com.redhat.dhcp.dbus.get.ip_address
        method return sender=:1.3 -> dest=:1.8
        1 uint32 2001735852

        $ /usr/bin/dbus-send  --system --dest=com.redhat.dhcp \
                              --type=method_call --print-reply \
                              --reply-timeout=20000 /com/redhat/dhcp/eth0 \
                              com.redhat.dhcp.dbus.format.get.routers
        method return sender=:1.228 -> dest=:1.251
        0 byte 3
        1 string "IA"
        2 byte 1
        3 string "dhcp"
        4 string "routers"
        5 byte 0

    The format.get methods return the DHCP option definition as defined in
    'dhcp_options.h'.  The first byte value is the dhcp option type code,
    the same as is sent in the DHCP packet.  The second string value is the
    DHCP type string.  The third byte value is the DHCP "Universe" or
    "Option Space" code.  The fourth string value is the DHCP universe name.
    The fifth string value is the real DHCP name of the option - ie. the
    real DHCP option name.  The sixth byte value is a boolean, being 1 if
    the option was user defined, 0 otherwise.

    NOTE:  Hyphens in DHCP option names are converted to underscores for
    D-BUS member names - ie.  'domain-name-servers' must be passed as the
    D-BUS member 'domain_name_servers' because D-BUS does not accept hyphens
    in member names.

User Defined Options and Option Spaces:

    dhcdbd and ISC dhclient with the '-x' patch in Red Hat dhclient-3.0.2-12+
    fully supports user defined options and option spaces; they will NOT be
    correctly supported without this dhclient version.
	
    Use of the dhclient '-x' option can be disabled by specifying
    "-DDHCLIENT_EXTENDED_OPTION_ENVIRONMENT=0" at compile time.

    For instance, if the client's dhclient.conf, and the server's dhcpd.conf,
    contain:
				 
        option space redhat;
        option redhat.routes code 1 = array of { ip-address, integer 8,
                                                 ip-address, integer 16,
                                                 integer 8 } ;

    And the server's dhcpd.conf contains:
	
        subnet ...{ ... option redhat.route
                    172.16.80.0 22 172.16.83.254 1 1,
                    192.168.10.0 24 192.168.10.254 2 1;... }

    And the client's dhclient.conf contains:

        request ... redhat.routes;

    Then these routes will be populated in the dhcdbd options and returned
    in response to gets.

Bug Reports:

    https://bugzilla.redhat.com/bugzilla/enter_bug.cgi?component=dhcdbd
