// DHCP message format

struct DHCP_MESSAGE
{
   union
   {
      char buffer[1];
      u_int8_t msg_type;		// Message type
   } u_msg_type;
	
   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				// Duid type
   {
	char buffer[2];
	u_int16_t duid_type;
   } u_duid_type;

   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;
   
    union
    {
	char buffer[4];
        u_int32_t time;			// Statically generated time value
    } u_time;
    
   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;
   
   int domain_name_len;
   u_int8_t *identifier;		// Identifier
   char *domain_name;			// 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;

   u_int8_t status;			// IA status code
   struct OPTIONS *opt;			// Pointer to IA Address option structur					// e
};

// 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;		// The server 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
};

// Interface details structure

struct interface
{
    u_int16_t duid_type, identifier_length;
    u_int32_t time;
    u_int16_t haddr_type, haddr_len;
    u_int8_t *haddr, *identifier;
    int domain_name_len;
    
    char *domain_name;
    struct in6_addr *link_local_addr;
    
    // Optional hints for values
    
    struct in6_addr *pref_ipv6_addr;
    u_int32_t pref_lifetime, valid_lifetime;
};
