// DHCP message format
struct DHCP_MESSAGE
{
   union
   {
      char buffer[1];
      u_int8_t msg_type;		// Message type
   } u_msg_type;
   char rev[3];	
   union
   {
      char buffer[4];
      u_int32_t trans_id;		// Transaction ID
   } u_trans_id;
	
   struct OPTIONS *opt;			// Pointer to OPTIONS structure
};

// Options format
struct OPTIONS
{
   union
   {
      char buffer[2];
      u_int16_t opt_code;		// Type of option
   } u_opt_code;

   union
   {
      char buffer[2];
      u_int16_t opt_len;		// Length of option data (in octets)
   } u_opt_len;
	
   void *opt_data;			// Pointer to option data structure   
};
   
// DUID structure
struct DUID
{
   union
   {
	char buffer[2];
	u_int16_t duid_type;		// Type of DUID
   } u_duid_type;
   char rev[2];
   void *duid_type;			// Pointer to duid type structure
   struct OPTIONS *opt;			// Pointer to next option
};

//DUID type 1
struct DUID1
{
   union
   {
	char buffer[2];
	u_int16_t haddr_type;		// Hardware type
   } u_haddr_type;
   char rev1[2];    //bruce
   union
   {
	char buffer[4];
	u_int32_t time;			// Time
   } u_time;
   char rev2[2];    //bruce
   u_int16_t haddr_len;			// Hardware address length
   u_int8_t *link_layer_address;	// Hardware address
};

// DUID type 2
struct DUID2
{
    union
    {
	char buffer[2];
	u_int16_t identifier_length;	// Identifier length
    } u_identifier_length;
    char rev[2];
    u_int8_t *identifier;		// Identifier
    int domain_name_len;
    char *domain_name;
};
    
//DUID type 3
struct DUID3
{
   union
   {
	char buffer[2];
	u_int16_t haddr_type;		// Hardware type
   } u_haddr_type;
   
   u_int16_t haddr_len;			// Hardware address length
   u_int8_t *link_layer_address;	// Hardware address
};

// IA option structure
struct IA
{
   union
   {
	char buffer[4];
	u_int32_t iaid;			// IAID
   } u_iaid;
   
   union
   {
	char buffer[4];
	u_int32_t t1;			// T1
   } u_t1;

   union
   {
	char buffer[4];
	u_int32_t t2;			// T2
   } u_t2;
    char rev[3];
   u_int8_t status;			// IA status code
   struct OPTIONS *opt;			// Pointer to IA Address option structure
};

// IA Address option structure
struct IA_ADDRESS
{
   int t_bit;			// (Temporary address or not) 1 BIT
   char addr_status;		// (Status of the address) 7 BITS
   u_int8_t prefix_length;	// Prefix length of the address
   u_int8_t addr[16];		// IPv6 address

   union
   {
	char buffer[4];
	u_int32_t pref_lifetime;	// Preferred lifetime
   } u_pref_lifetime;

   union
   {
	char buffer[4];
	u_int32_t valid_lifetime;	// Valid lifetime
   } u_valid_lifetime;

   void *ia_addr_opt;			// IA Address options = NULL (for now)
   struct OPTIONS *opt;			// Pointer to next option
};

// Preference option
struct PREFERENCE
{
    u_int8_t preference_value;
    struct OPTIONS *opt;
};

// Status code option
struct STATUS_CODE
{
   union
   {
	char buffer[2];
	u_int16_t status_code;	// Status code
   } u_status_code;
   
   char *message;			// Status message
   struct OPTIONS *opt;		// Pointer to next option
};

// elapsed time option          //add by bruce
struct ELAPSED_TIME
{
   union
   {
	char buffer[2];
	u_int16_t elapsed_time;	// elapsed time
   } u_elapsed_time;
   
   struct OPTIONS *opt;		// Pointer to next option
};

//unsupport struct
struct UN_SUPPORT
{
    struct OPTIONS *opt;		// Pointer to next option
};

// Head node of the config file linked list
struct config_head
{
    u_int32_t t1, t2;
    int first_node_type;
    void *next;
};

// Range node of configuration file
struct config_range
{
    struct in6_addr *st_addr, *end_addr;
    u_int32_t pref_life, valid_life;
    int max_renew_count, pref_val;
    int next_node_type;
    void *next;
};

// User node of the configuration file
struct config_user
{
    struct in6_addr *link_local_addr, *ipv6_addr;
    u_int32_t pref_life, valid_life;
    int max_renew_count, pref_val;
    int next_node_type;
    void *next;
};

// Lease details
struct lease_details
{
    union
    {
	char buffer[4];
	u_int32_t iaid;
    } u_iaid;
   
   union
   {
      char buffer[4];
      u_int32_t trans_id;
   } u_trans_id;
	
    union
    {
	char buffer[4];
	u_int32_t t1;
    } u_t1;

    union
    {
	char buffer[4];
	u_int32_t t2;
    } u_t2;

    union
    {
	char buffer[4];
	u_int32_t pref_lifetime;
    } u_pref_lifetime;

    union
    {
	char buffer[4];
	u_int32_t valid_lifetime;
    } u_valid_lifetime;

    int max_renew_count, renew_count;
    struct in6_addr assigned_ipv6_addr;
    u_int8_t prefix_length;
    struct DUID *client_duid;
    time_t start_time;			// Null for partial leases
    struct lease_details *next;		// Link to next node
};

// Address details
struct addr_details
{
    u_int32_t t1, t2;
    u_int32_t pref_life, valid_life;
    int max_renew_count, pref_val;
    struct in6_addr ipv6_addr;
};
