DHCPv6 Client

(Redirected from DHCPv6)
Jump to: navigation, search

DHCPv6 Client Description

This section of the manual describes the general usage and operation of the DHCPv6 client, as well as an overview of the DHCPv6 protocol.

Introduction

The DHCPv6 client allows user to automatically obtain IPv6 configuration information from a DHCPv6 server. It works side-by-side with stateless address autoconfiguration. It performs server discovery, requests addresses, automatically performs address renewal and rebinding, deprecates addresses when the preferred lifetime elapses, removes addresses when the valid lifetime elapses, and releases addresses when unconfigured or when the interface is closed.

Protocol Operation

When started, the DHCPv6 client will transmit Solicit messages until it receives a response from a server in the form of an Advertise message. The client will then send either a Request message (asking for addresses and configuration information) or an Information-Request message (asking only for configuration information) to the server. The server responds with a Reply message containing the requested data.

Addresses are contained within a conceptual object known as an IA (Identity Association). Each address must be contained within an IA, and an IA may contain more than one address. Certain aspects of address management pertain to IAs, while others pertain directly to the addresses. This distinction is important when discussing the four timers (set by the server) that govern address lifetmes: T1, T2, preferred, and valid.

The first two timers, T1 and T2, pertain to IAs (and, thus, to all addresses contained within the IA). These timers instruct the client when to start sending Renew and Rebind messages, respectively. The Renew message is sent by the client to the server that granted the IA to renew the lifetimes for addresses within the IA. If no Reply is received by the time T2 expires, the client begins sending Rebind messages, which are similar to Renew but are sent to any DHCPv6 server on the local link. These messages continue until a Reply is received or all address lifetimes have expired.

The second set of timers, preferred and valid, pertains directly to addresses. When an address reaches its preferred lifetime timeout, it is deprecated within the stack to discourage further use. When an address reaches the end of its valid lifetime, it is removed from the interface and routing table.

At any time, the user may request that the client send a Confirm message to ensure the addresses it has are still valid. This is useful, for example, if the user believes the client has changed networks. A server should send a Reply message to the Confirm, informing the client of the validity of the addresses. If no Reply is received, the user must choose whether to continue to use the addresses it has or release them. When the client no longer needs the addresses, such as when the user unconfigures the interface, it sends a Release message to the server to relinquish the addresses.

If the client and server have authenticated each other, the server may send a Reconfigure message to the client, instructing it to request new configuration information by sending either a Request or Information-Request message

Throughout the operation of DHCPv6, message retransmission is governed by four different values. Each message type has a set value for each of the following variables: IRT (Initial Retransmission Timeout), MRT (Maximum Retransmission Time), MRD (Maximum Retransmission Duration), and MRC (Maximum Retransmission Count).

IRT is the amount of time that must expire before sending the first retransmission. After that, each retransmission timeout takes twice as long as the previous, up to the MRT. Once the retransmission timeout reaches the MRT, it does not grow any longer.

Message retransmission ceases when either the MRC or MRD is reached. The MRC is the total number of transmissions of the message that can be sent, including the first message. MRD is the total amount of time during which the client may retransmit a message, starting when the initial transmission of the message is sent.

Compiling the DHCPv6 Client

The DHCPv6 client code is encapsulated by the macro TM_6_USE_DHCP. This macro must be defined in <trsystem.h> to include the DHCPv6 client code when compiling the stack.

Initializing the DHCPv6 Client

tf6UseDhcp() allocates memory and initializes the DHCPv6 client. This function must be called before any other DHCPv6 APIs.

Configuring Client Behavior

Before starting the DHCPv6 client, the user may call tf6DhcpSetOption() to configure aspects of the client's behavior, such as the MRD of certain messages.

Configuring Requested Parameters and Addresses

Before starting the DHCPv6 client, user may set configuration parameters and addresses to request from the server with the following APIs:

  • tf6DhcpSetIaOption()
    Sets user-requested configuration options, including rebind and renewal (T1 and T2) timeouts
  • tf6DhcpSetAddrOption()
    Sets user-requested address, as well as the preferred lifetime and valid lifetime of the address

Configuring FQDN

Before starting the DHCPv6 client, the user may configure the FQDN option using tfInterfaceSetOptions(). This API allows the user to configure a fully qualified or partial domain name to suggest to the server. It also allows the user to suggest whether the client or the server should be responsible for DNS updates. The server is not required to use any of the information given to it by the client and may choose new settings.

Configuring Authentication

Authentication is not required for DHCPv6 to operate. However, it must be in use for Reconfigure messages to be processed. Authentication may be configured using the following APIs:

  • tf6DhcpUserAddKey()
    Stores keys for use with the authentication option. At least one key must be stored before starting DHCPv6 for authentication to work. Key management is done out-of-band; management of key distribution and lifetimes is left entirely to the user.
  • tf6DhcpUserRemoveKey()
    Remove a key from use by DHCPv6 authentication
  • tf6DhcpUserUpdateKey()
    Change a key being used by DHCPv6 authentication
  • tf6DhcpUserConfigAuth()
    Select the authentication protocol and cryptography algorithm. For authentication to be used, this must be called before DHCPv6 is started.
  • tf6DhcpUserSetRdm()
    Set the current value of the replay detection method (RDM) field. If you have saved the RDM from the previous DHCPv6 session, it should be set before starting DHCPv6.
  • tf6DhcpUserGetRdm()
    Retrieve the current value of the RDM field. This should done before DHCPv6 shuts down.

Configuring the Rapid Commit Option

The Rapid Commit option is an optional module that is disabled by default. It must be enabled globally with the TM_6_DHCP_USE_RAPID_COMMIT macro in trsystem.h and on each interface with function tfInterfaceSetOptions(), option TM_6_DEV_OPTIONS_DHCP_RAPID_CMT.

When enabled, it allows the Treck DHCPv6 client to be configured using a Solicit and Reply message exchange with a server that also supports the Rapid Commit option.

See the main section below for more details.

Starting the DHCPv6 Client

The DHCPv6 client can be launched by the either tfNgOpenInterface() or tfNgConfigInterface(). If tfNgConfigInterface() is called, the multiHomeIndex parameter is ignored. The ipv6flags parameter of these APIs supports the following DHCPv6 flags:

  • TM_6_DEV_USER_DHCP
    The DHCPv6 client will be started on this interface when the interface is opened.
  • TM_6_DEV_USER_DHCP_INFO_ONLY
    This flag is set in conjunction with TM_6_DEV_USER_DHCP to instruct the client to do an Information-Request exchange rather than a standard exchange. If this option is set, no addresses will be retrieved from the server.
  • TM_6_DEV_USER_DHCP_RTR_CTRLD
    The DHCPv6 client is controlled by the Managed and Other flags received in IPv6 Router Advertisements. When a router advertisement is received, the stack checks if either the M or the O flag is set. If the O flag (but not the M flag) is set, a DHCPv6 Info-Request packet is sent. If the M flag is set, full DHCPv6 address configuration occurs. Once the M flag has been received, the DHCPv6 address configuration will stay in effect until the interface in question has been closed, even if subsequent Router Advertisement packets are received in which the M flag is not set. If an O flag is received first, then an M flag is received subsequently, the DHCPv6 client will perform full address configuration upon receipt of the M flag.
  • TM_6_DEV_USER_DHCP_CONF_OPEN
    This flag is set in conjunction with TM_6_DEV_USER_DHCP to instruct the client to do a Confirm and Reply message exchange rather than a standard exchange. You must define compile time macro TM_6_DHCP_USE_CONF_OPEN to enable the code that supports this option. If this option is set, you must also use tf6DhcpSetAddrOption() to set at least one address to send in the Confirm message. This could be used when rebooting to verify and reconfigure an address that was previously configured on the interface by DHCPv6.

As of version 5.0.1.39, the DHCPv6 negotiation will be delayed until after the link-local address has completed Duplicate Address Detection.

Note Note: Any addresses obtained by DHCPv6 (using any of the methods listed above) are automatically configured for use. No further action is required by the user.
Note Note: If you shut down the DHCPv6 client, you must wait for the event TM_6_DHCP_EVENT_STOPPED before starting it again. Please see the Callback Handling section below for more details.

Handling DHCPv6 Client Callbacks

The DHCPv6 client can send notification events to the user through two separate callback functions. The fist is the interface callback function registered with tfNgOpenInterface() or tfNgConfigInterface(). The second is the DHCPv6 client callback function registered with tf6UseDhcp(). The meaning of events passed to these callbacks, as well as how to handle them, is discussed below in the Callback Handling section.

Releasing Addresses and Stopping the DHCPv6 Client

tf6DhcpUserStop() will release all DHCPv6 addresses, stop the DHCPv6 client and reset all DHCPv6 configuration information.

tfCloseInterface() will release all DHCPv6 addresses and stop the DHCPv6 client as part of the interface close process.

tfNgUnConfigInterface() will release the DHCPv6 addresses associated with the given multihome index. If it is the last remaining DHCPv6 address, the DHCPv6 client will be stopped.

Accessing Granted Configuration Information

  • tf6DhcpGetBootEntry()
    Get DHCPv6 information received from the server. The user must free the boot entry when it is no longer needed.
  • tf6DhcpFreeBootEntry()
    Free the user boot entry. The entry must not be accessed once it has been freed. Note that this only frees the structure allocated by tf6DhcpGetBootEntry(); it does not affect the internal configuration information and configured addresses

Confirming the Configuration Status

tf6DhcpConfirm() may be used to verify that the address configuration information is valid for current network. This should called when the client may have moved to a new link.

Usage Scenario

This is a common usage scenario for the DHCPv6 client:

  1. Call tf6UseDhcp() to enable DHCPv6 on the interface
  2. Call tf6DhcpSetIaOption() to set the preferred T1 and T2 times (optional)
  3. Call tf6DhcpSetAddrOption() to set the preferred IP address and its lifetimes (optional)
  4. Call tfInterfaceSetOptions() as necessary to configure the FQDN and Rapid Commit options (optional)
  5. Call tf6DhcpUserAddKey() to store a key for use with DHCPv6 authentication (optional)
  6. Call tf6DhcpUserConfigAuth() to configure the authentication option (optional)
  7. Call tf6DhcpUserSetRdm() to store the value of the RDM field for use by the authentication option (optional)
  8. Call tfNgOpenInterface() or tfNgConfigInterface() with TM_6_DEV_USER_DHCP to start the DHCPv6. Any addresses obtained are automatically configured for use.
  9. Call tf6DhcpGetBootEntry() any time after negotiation has completed to access the configuration information obtained by DHCPv6. Call tf6DhcpFreeBootEntry() to free the boot entry information when it is no longer needed by the user.
  10. Call tf6DhcpUserRemoveKey() or tf6DhcpUserUpdateKey() to manage keys being used by DHCPv6 authentication.
  11. Call tf6DhcpConfirm() when the client has possibly moved to a new link
  12. Call tf6DhcpUserGetRdm() to retrieve the current value of the RDM field used by the authentication option before DHCPv6 is stopped.
  13. Call tf6DhcpUserStop(), tfCloseInterface() or tfNgUnConfigInterface() to release addresses to the server when they are no longer needed. DHCPv6 will be stopped and reset when all addresses are released.

Using the Confirm Message to Reboot the DHCPv6 Client

RFC 3315, section 18.1.2 discusses how a DHCPv6 client might use a Confirm message to verify its addresses on the current link after undergoing a reboot or deep sleep. This section describes how a user could reboot the Treck DHCPv6 client in such a manner.

To enable the code that supports this option, uncomment the following compile time macro in trsystem.h:

#define TM_6_DHCP_USE_CONF_OPEN

DHCPv6 client reboot by Confirm message presupposes that you know what addresses were autoconfigured on an interface prior to rebooting the Treck stack. The following steps provide an example of how to use this option:

  1. Discover what addresses are autoconfigured on an interface via DHCPv6 by monitoring the IPv6 Address Configuration Events described on the tfNgOpenInterface() page. In particular, TM_6_DEV_ADDR_CONFIG_COMPLETE, TM_6_DEV_ADDR_INVALIDATED, TM_6_DEV_ADDR_CONFIG_FAILED and TM_6_DEV_ADDR_DUP_DETECTED tell you what addresses have been configured, unconfigured or have encountered a duplicate address on another node.
  2. Store all valid autoconfigured addresses in non-volatile memory.
  3. Reboot or power down until awakened by some external event.
  4. Start Treck as you normally would with tfStartTreck(), etc.
  5. Call tf6UseDhcp() and tf6DhcpSetAddrOption() to initialize DHCPv6 and set your preferred addresses (the autoconfigured IPv6 addresses you stored in non-volatile memory).
  6. When you open your interface this time, include the TM_6_DEV_USER_DHCP_CONF_OPEN and TM_6_DEV_USER_DHCP flags when calling tfNgOpenInterface() (or tfNgConfigInterface() for additional addresses).
  7. Wait for the TM_6_DEV_ADDR_CONFIG_COMPLETE event for the address that is of interest to you. Your DHCPv6 autoconfigured address would have a multiHomeIndex between (TM_MAX_IPS_PER_IF + TM_6_MAX_AUTOCONF_IPS_PER_IF) and (TM_MAX_IPS_PER_IF + TM_6_MAX_AUTOCONF_IPS_PER_IF + TM_6_MAX_DHCP_IPS_PER_IA - 1).

To achieve a successful reboot, the Treck DHCPv6 client must receive a Reply message with a success status option from a server. If a success Reply message is not received (as a result of an error Reply message or no Reply message at all), the Treck DHCPv6 client will initiate the DHCPv6 server discovery phase by sending a Solicit message.

Warning Warning: The Treck DHCPv6 client diverges from RFC 3315 if there is no response to the Confirm message we sent for reboot. The RFC states, "the client SHOULD continue to use any IP addresses, using the last known lifetimes for those addresses, and SHOULD continue to use any other previously obtained configuration parameters." When rebooting, the Treck DHCPv6 client does not have enough state information to continue after an unsuccessful Confirm message and must restart server discovery.

Related information can be found at Fast Reboot when using Autoconfigured Addresses.

Optional Modules

FQDN

The FQDN option for DHCPv6 allows the user to request a domain name from the DHCPv6 server. The user may provide a full (e.g. fqdn1.treck.com) or partial (e.g. fqdn1) domain name as a hint to the server. The user may also provide hints to the server about who is responsible for performing DNS updates related to the FQDN name. The server is not required to obey these hints.

Please see TM_6_DHCP_USE_FQDN and TM_6_DHCP_FQDN_MAX_ASCII_LEN in the Macro Reference section as well as tfInterfaceSetOptions() and tf6DhcpGetBootEntry() in the Function Reference section.

Authentication

DHCPv6 authentication allows the protocol to operate safely over open networks, helping prevent potential denial of service attacks or intentional misconfiguration by hostile nodes.

DHCPv6 authentication provides a framework under which various authentication protocols may be employed. Currently, only DAP (Delayed Authentication Protocol) is implemented. DAP allows the client and server to verify each other's identity via a cryptologic hash included in the DHCPv6 packet. Clients and servers possessing the correct credentials can verify this hash, thereby confirming the identity of the other party. The credentials used by DAP are distributed out-of-band and are not part of the DHCPv6 protocol.

Authentication also allows the use of Reconfigure messages. The server sends a Reconfigure message to instruct the client to request new configuration information. Because of the potential for abuse, this message type must be ignored unless it passes authentication.

Please see TM_6_DHCP_USE_AUTH in the Macro Reference section as well as tf6DhcpUserConfigAuth(), tf6DhcpUserAddKey(), tf6DhcpUserRemoveKey(), tf6DhcpUserUpdateKey(), tf6DhcpUserSetRdm() and tf6DhcpUserGetRdm() in the Function Reference section.

Rapid Commit Option

A DHCPv6 client will send a Solicit message to discover the DHCPv6 servers and begin the assignment of IPv6 addresses and other configuration information. If a server is prepared to commit addresses to a client immediately upon receipt of a Solicit message, the server can send a Reply message with a Rapid Commit option instead of sending an Advertise message. The DHCPv6 client can indicate support by including the Rapid Commit option in the Solicit message.

By default, this feature is omitted to reduce code space. To support the Rapid Commit option, include the following macro definition in your trsystem.h:

#define TM_6_DHCP_USE_RAPID_COMMIT

This feature is supported on a per interface basis and is disabled on all interfaces, by default. To enable the Rapid Commit option on an interface, call tfInterfaceSetOptions() to set option TM_6_DEV_OPTIONS_DHCP_RAPID_CMT prior to opening the interface with the TM_6_DEV_USER_DHCP flag (see tfNgOpenInterface() or tfNgConfigInterface()).

Macro Reference

These macros can be defined in <trsystem.h> to affect the behavior of the DHCPv6 client.

For more details see the DHCPv6 Option Macros section of the Compile Time Macros page.

TM_6_USE_DHCP
TM_6_MAX_DHCP_IPS_PER_IA
TM_6_DHCP_USE_FQDN
TM_6_DHCP_FQDN_MAX_ASCII_LEN
TM_6_DHCP_USE_AUTH
TM_6_DHCP_USE_RAPID_COMMIT
TM_6_DHCP_USE_CONF_OPEN

Function Reference

tf6UseDhcp()
tf6DhcpUninitialize()
tf6DhcpSetOption()
tf6DhcpSetIaOption()
tf6DhcpSetAddrOption()
tf6DhcpGetBootEntry()
tf6DhcpFreeBootEntry()
tf6DhcpConfirm()
tf6DhcpUserStop()
tfInterfaceSetOptions()
tf6DhcpUserConfigAuth()
tf6DhcpUserAddKey()
tf6DhcpUserRemoveKey()
tf6DhcpUserUpdateKey()
tf6DhcpUserSetRdm()
tf6DhcpUserGetRdm()
tf6DhcpUserRegisterAdvOptCb()

Callback Handling

DHCPv6 Callback Function Event Handling

These following events may be passed to the callback function registered with tf6UseDhcp():

  • TM_6_DHCP_EVENT_SOLICIT_TIMEOUT
    By default, this event will never occur because Solicit messages will retransmit forever if no server replies. If the a timeout has been configured for Solicit messages via tf6DhcpSetOption(), this event will occur when the specified timeout has elapsed without a response from a server.
    When this event occurs, the DHCPv6 client ceases operation. It does not reset any configuration information stored with tf6DhcpSetIaOption() or tf6DhcpSetAddrOption(). It can be started again via a call to tfNgOpenInterface() or tfNgConfigInterface().
  • TM_6_DHCP_EVENT_NO_SERVER
    This event can occur in two situations. The first is during the initial address negotiation. If the selected server never replies to the client's initial Request message, this event will occur.
    The second situation is when trying to extend the lifetimes of addresses. If the server never replies to any Renew or Rebind messages, the valid lifetime of the addresses will eventually expire and this event will occur.
    When this event occurs, the DHCPv6 client automatically resets to the Solicit phase and begins looking for new servers. All tf6DhcpSetIaOption() and tf6DhcpSetAddrOption() settings are forgotten. The user does not need to take any action except, perhaps, to set new options.
  • TM_6_DHCP_EVENT_INFO_RECEIVED
    This event occurs when the DHCPv6 client receives a valid Reply from the server in response to an Information-Request message. The user may call tf6DhcpGetBootEntry() to retrieve the configuration information.
  • TM_6_DHCP_EVENT_LEASE_RENEWED
    This event occurs when the lifetime of addresses is successfully extended. The user may call tf6DhcpGetBootEntry() to retrieve the new lifetimes.
  • TM_6_DHCP_EVENT_CONFIRM_OK
    This event occurs when the Confirm message exchange has completed successfully. Note that no response from the server is considered successful, as in that circumstance the client is entitled to continue using the addresses and configuration information it received.
  • TM_6_DHCP_EVENT_CONFIRM_FAILED
  • This event occurs when the client receives an error from the server indicating that it has moved to a new link.
    When this event occurs, the DHCPv6 client automatically deletes all of the affected addresses, resets to the Solicit phase, and begins looking for new servers. The user does not need to take any action.
  • TM_6_DHCP_EVENT_STOPPED
    This event occurs when the DHCPv6 client is shutting down. When this event occurs, the DHCPv6 client completely reinitializes. All DHCPv6 configuration information is reset and must be reconfigured. The client may be started again via a call to tfNgOpenInterface() or tfNgConfigInterface().
    If DHCPv6 authentication is being used, tf6DhcpUserGetRdm() should be called from inside the callback when this event occurs.
Note Note: After stopping DHCPv6 via tf6DhcpUserStop(), tfCloseInterface(), or tfNgUnConfigInterface(), you must wait for TM_6_DHCP_EVENT_STOPPED before restarting DHCPv6. You may not restart DHCPv6 from within the callback function.

Interface Callback Function Event Handling

These following events may be generated by the DHCPv6 client and passed to the callback function registered with tfNgOpenInterface() or tfNgConfigInterface(). The callback function identifies addresses by their multihome index. The maximum number of DHCPv6 addresses is defined by TM_6_MAX_DHCP_IPS_PER_IA and the multihome index range of DHCPv6 addresses can be calculated as follows:

(TM_MAX_IPS_PER_IF + TM_6_MAX_AUTOCONF_IPS_PER_IF) <=
DHCPv6 Multihome Index Range <
(TM_MAX_IPS_PER_IF + TM_6_MAX_AUTOCONF_IPS_PER_IF + TM_6_MAX_DHCP_IPS_PER_IA)
  • TM_6_DEV_ADDR_ALL_DECLINED
    All DHCPv6 addresses offered by the server have been declined due to failed duplicate address detection.
  • TM_6_DEV_ADDR_DEPRECATED
    The Preferred lifetime of the specified address has expired and the address has been deprecated.
  • TM_6_DEV_ADDR_PREFERRED
    The lifetime of the specified address has been extended and it has been restored to preferred status.
  • TM_6_DEV_ADDR_INVALIDATED
    The Valid lifetime of the specified address has expired and the address has been removed from the interface.


Note Note: There is no callback to indicate that a single address has been released because it is unnecessary. This is because tfCloseInterface() will always remove all addresses and tfNgUnConfigInterface() instantly removes the requested address.
Note Note: After removing all DHCPv6 addresses via tf6DhcpUserStop(), tfCloseInterface(), or tfNgUnConfigInterface(), DHCPv6 may not be restarted until the TM_6_DHCP_EVENT_STOPPED event has occurred. You may not restart the client from inside the callback function.

Application Example

User Event Notification Function Example

/* DHCPv6 user event notification function type */
void myDhcpv6NotifyFunc(ttUserInterface interfaceHandle,
                        int             iaIndex,
                        int             addrIndex,
                        tt6DhcpEvent    event)
{
    TM_UNREF_IN_ARG(interfaceHandle);
    TM_UNREF_IN_ARG(iaIndex);
    TM_UNREF_IN_ARG(addrIndex);
    TM_UNREF_IN_ARG(event);
}

User Application Code Example

/* Example DHCPv6 application code */
void tfx6DhcpConfig(ttUserInterface interfaceHandle)
{
    ttUser64Bit rdmVal;
    int errorCode;
    struct sockaddr_storage sockAddr;
    ttUser32Bit entNum = 0x01010101;
    ttUser8Bit entId[] = "treckinc";
    struct in6_addr ipAddr;
    ttUser8Bit byteOpt;
 
/* Use DHCP */
    errorCode = tf6UseDhcp(interfaceHandle,
                            myDhcpv6NotifyFunc,
                            entNum,
                            entId,
                            tm_strlen(entId),
                            1,
                            0);
    tm_assert(tfx6DhcpConfig, errorCode == TM_ENOERROR);
    tm_bzero(&sockAddr, sizeof(sockAddr));
    sockAddr.ss_family = AF_INET6;
    sockAddr.ss_len = sizeof(sockAddr);
/* Set IA options */
    errorCode = tf6DhcpSetIaOption(interfaceHandle,
                                    0,
                                    1000,
                                    2000,
                                    0);
    tm_assert(tfx6DhcpConfig, errorCode == TM_ENOERROR);
/* Set Adddress options */
    tm_memset(&ipAddr, 1, sizeof(ipAddr));
    errorCode = tf6DhcpSetAddrOption(interfaceHandle,
                                        0, 
                                        0, 
                                        &ipAddr, 
                                        2000, 
                                        3000, 
                                        0);
    tm_assert(tfx6DhcpConfig, errorCode == TM_ENOERROR);
#ifdef TM_6_DHCP_USE_FQDN
    tfInterfaceSetOptions(interfaceHandle,
                            TM_6_DEV_OPTIONS_DHCP_FQDN_PART,
                            "treck1",
                            6);
#endif /* TM_6_DHCP_USE_FQDN */
#ifdef TM_6_DHCP_USE_RAPID_COMMIT
/* Enable Rapid Commit option on the interface */
    byteOpt = 1;
    tfInterfaceSetOptions(interfaceHandle,
                            TM_6_DEV_OPTIONS_DHCP_RAPID_CMT,
                            &byteOpt,
                            sizeof(byteOpt));
#endif /* TM_6_DHCP_USE_RAPID_COMMIT */
#ifdef TM_6_DHCP_USE_AUTH
    tf6DhcpUserAddKey(interfaceHandle,
                        "realm1",
                        6,
                        1,
                        "secret",
                        6,
                        0);
    tf6DhcpUserConfigAuth(interfaceHandle,
                            TM_6_DHCP_AUTH_PROTO_DELAYED,
                            TM_6_DHCP_AUTH_ALG_MD5,
                            TM_6_DHCP_AUTH_RDM_MONO_INC,
                            0);
/* Set initial RDM value to 100. This should actually be set to
 * the last value retrieved from tf6DhcpUserGetRdm() 
 */
    rdmVal.uu64hi = 0;
    rdmVal.uu64low = 100;
    tf6DhcpUserSetRdm(interfaceHandle,
                        &rdmVal,
                        0);
#endif /* TM_6_DHCP_USE_AUTH */
/* Open interface */
    errorCode = tfNgOpenInterface(interfaceHandle,
                                    &sockAddr,
                                    0,
                                    0,
                                    TM_6_DEV_USER_DHCP,
                                    1,
                                    TM_6_DEV_ADDR_NOTIFY_FUNC_NULL_PTR);
    tm_assert(tfx6DhcpConfig,
                (errorCode == TM_ENOERROR)
                || (errorCode == TM_EINPROGRESS));
}