Files
m241Neelima/components/ip_net2-6.9/ipdhcps6/src/ipdhcps6_authhash.c
T
2026-07-30 11:19:44 +05:30

894 lines
27 KiB
C

/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Copyright (C) 2007 Wind River Systems
*
******************************************************************************
*/
/*
modification history
--------------------
01a,17jul07,ps initial checkin of dhcpv6 authentication key database module
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_type.h>
#include <ipcom_cstyle.h>
#include <ipcom_clib.h>
#include <ipcom_err.h>
#include <ipcom_list.h>
#include <ipcom_syslog.h>
#include <ipcom_sysvar.h>
#include <ipnet.h>
#include <ipnet_routesock.h>
#include "ipdhcps6.h"
#include "ipdhcps6_h.h"
#include "ipdhcps6_host.h"
#include "ipdhcps6_prefix.h"
#include "ipdhcps6_subnet.h"
#include "ipdhcps6_duid.h"
#include "ipdhcps6_cvthex.h"
#include "ipdhcps6_authhash.h"
#define IPDHCPS6_DUID_LL_ACTUALSIZE 10
#define IPDHCPS6_DUID_LLT_ACTUALSIZE 14
#define IPDHCPS6_DUID_EN_ACTUALSIZE 14
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipdhcps6_authdata_obj_hash
*===========================================================================
* Description: Returns a hash value based on an authkey value.
* Parameters: dbentry - The option to return a hash value for.
* Returns:
*
*/
IP_STATIC unsigned
ipdhcps6_authdb_obj_hash (Ipdhcps6_authkey_dbentry *dbentry)
{
#ifdef DEBUG_DHCPV6_AUTH
int i;
unsigned char *cptr;
printf ("ipdhcps6_authdb_obj_hash called: ");
cptr = (unsigned char *) &(dbentry->duid.data.ll.link_addr);
for (i = 0 ; i < 6 ; i++)
{ printf ("%2x ", cptr [i]);
}
printf ("\n");
#endif
return ipcom_hash_update(&(dbentry->duid.data), dbentry->duid.len, 0);
}
/*
*===========================================================================
* ipdhcps6_authdb_key_hash
*===========================================================================
* Description: Returns a hash value for a DUID key.
* Parameters: key - Pointer to the Ipdhcps6_authkey_duid structure
* Returns:
*
*/
IP_STATIC unsigned
ipdhcps6_authdb_key_hash(Ipdhcps6_duid *key)
{
#ifdef DEBUG_DHCPV6_AUTH
int i;
unsigned char *cptr;
printf ("ipdhcps6_authdb_key_hash called: ");
cptr = (unsigned char *) &(key->data.ll.link_addr);
for (i = 0 ; i < 6 ; i++)
{ printf ("%2x ", cptr [i]);
}
printf ("\n");
#endif
return ipcom_hash_update(&(key->data), key->len, 0);
}
/*
*===========================================================================
* ipdhcps6_authdb_hash_cmp
*===========================================================================
* Description: Compares a hash object and a hash key for equality.
* Parameters: dbentry - An authkey_dbentry structure.
* key - A pointer to the search key.
* Returns: IP_TRUE if the search key matches the prefix entry.
*
*/
IP_STATIC Ip_bool
ipdhcps6_authdb_hash_cmp(Ipdhcps6_authkey_dbentry *dbentry, Ipdhcps6_duid *key)
{
#ifdef DEBUG_DHCPV6_AUTH
printf ("ipdhcps6_authdb_hash_cmp called\n");
#endif
if (dbentry->duid.len != key->len)
return IP_FALSE;
return ipcom_memcmp(&(dbentry->duid.data), &(key->data),
key->len) == 0;
}
/*************/
/*
*===========================================================================
* ipdhcps6_authtrans_obj_hash
*===========================================================================
* Description: Returns a hash value based on an authkey value.
* Parameters: dbentry - The option to return a hash value for.
* Returns:
*
*/
IP_STATIC unsigned
ipdhcps6_authtrans_obj_hash (Ipdhcps6_authtrans_dbentry *dbentry)
{
#ifdef DEBUG_DHCPV6_AUTH
int i;
unsigned char *cptr;
printf ("ipdhcps6_authtrans_obj_hash called: ");
cptr = (unsigned char *) &(dbentry->duid.data);
switch (dbentry->duid.data.generic.content)
{ case IPDHCPS6_DUID_LL:
printf ("LL content\n");
break;
case IPDHCPS6_DUID_LLT:
printf ("LLT content\n");
break;
case IPDHCPS6_DUID_EN:
printf ("EN content\n");
break;
default:
printf ("default case content\n");
}
for (i = 0 ; i < dbentry->duid.len ; i++)
{ printf ("%2x ", cptr [i]);
}
printf ("\n");
#endif
return ipcom_hash_update(&(dbentry->duid.data), dbentry->duid.len, 0);
}
/*
*===========================================================================
* ipdhcps6_authtrans_key_hash
*===========================================================================
* Description: Returns a hash value for a DUID key.
* Parameters: key - Pointer to the Ipdhcps6_authkey_duid structure
* Returns:
*
*/
IP_STATIC unsigned
ipdhcps6_authtrans_key_hash(Ipdhcps6_duid *key)
{
#ifdef DEBUG_DHCPV6_AUTH
int i;
unsigned char *cptr;
printf ("ipdhcps6_authtrans_key_hash called: ");
cptr = (unsigned char *) &(key->data);
switch (key->data.generic.content)
{ case IPDHCPS6_DUID_LL:
printf ("LL content\n");
break;
case IPDHCPS6_DUID_LLT:
printf ("LLT content\n");
break;
case IPDHCPS6_DUID_EN:
printf ("EN content\n");
break;
default:
printf ("default case content\n");
}
for (i = 0 ; i < key->len ; i++)
{ printf ("%2x ", cptr [i]);
}
printf ("\n");
#endif
return ipcom_hash_update(&(key->data), key->len, 0);
}
/*
*===========================================================================
* ipdhcps6_authtrans_hash_cmp
*===========================================================================
* Description: Compares a hash object and a hash key for equality.
* Parameters: prefix - A prefix structure.
* key - A pointer to the search key.
* Returns: IP_TRUE if the search key matches the prefix entry.
*
*/
IP_STATIC Ip_bool
ipdhcps6_authtrans_hash_cmp(Ipdhcps6_authtrans_dbentry *dbentry, Ipdhcps6_duid *key)
{
#ifdef DEBUG_DHCPV6_AUTH
printf ("ipdhcps6_authtrans_hash_cmp called\n");
#endif
if (dbentry->duid.len != key->len)
return IP_FALSE;
return ipcom_memcmp(&(dbentry->duid.data), &(key->data),
key->len) == 0;
}
/*****************/
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
IP_STATIC Ipcom_hash *client_authkey_db;
IP_STATIC Ipcom_hash *client_transaction_db;
IP_GLOBAL Ipcom_hash *
ipdhcps6_authdb_hash_create(void)
{
return ipcom_hash_new ((Ipcom_hash_obj_func) ipdhcps6_authdb_obj_hash,
(Ipcom_hash_key_func) ipdhcps6_authdb_key_hash,
(Ipcom_hash_cmp_func) ipdhcps6_authdb_hash_cmp);
}
IP_GLOBAL Ipcom_hash *
ipdhcps6_authtrans_hash_create(void)
{
return ipcom_hash_new ((Ipcom_hash_obj_func) ipdhcps6_authtrans_obj_hash,
(Ipcom_hash_key_func) ipdhcps6_authtrans_key_hash,
(Ipcom_hash_cmp_func) ipdhcps6_authtrans_hash_cmp);
}
IP_GLOBAL Ipdhcps6_duid *ipdhcps6_authdb_create_ll_duid (int len, Ip_u16 hwtype, Ip_u8 *link_addr)
{
Ipdhcps6_duid *retval = (Ipdhcps6_duid *)
ipcom_malloc (sizeof (struct Ipdhcps6_duid_struct));
(void)len;
if (IP_NULL == retval)
return IP_NULL;
retval->len = IPDHCPS6_DUID_LL_ACTUALSIZE;
retval->data.ll.content = IPDHCPS6_DUID_LL;
retval->data.ll.hardware_type = hwtype;
ipcom_memcpy (retval->data.ll.link_addr, link_addr, 6);
return retval;
}
IP_GLOBAL Ip_err ipdhcps6_add_client_authkey (Ipdhcps6_duid *client_duid,
Ip_u8 *key, int keylen)
{
Ip_u16 duid_content;
Ipdhcps6_authkey_dbentry *new_authdb_entry = (Ipdhcps6_authkey_dbentry *)
ipcom_malloc (sizeof (struct Ipdhcps6_authkey_dbentry));
if (IP_NULL == new_authdb_entry)
return IPCOM_ERR_FAILED;
new_authdb_entry->secret.key = (Ip_u8 *) ipcom_malloc ((Ip_size_t)keylen);
if (IP_NULL == new_authdb_entry->secret.key)
{ ipcom_free (new_authdb_entry);
IPCOM_LOG0 (DEBUG, "ipdhcps6_add_client_authkey: no memory!\n");
return IPCOM_ERR_NO_MEMORY;
}
/*
* copy in key
*/
ipcom_memcpy (new_authdb_entry->secret.key, key, (Ip_size_t)keylen);
new_authdb_entry->secret.len = keylen;
/*
* copy in duid data
*/
new_authdb_entry->duid.len = client_duid->len;
duid_content = client_duid->data.ll.content;
switch (duid_content)
{
case IPDHCPS6_DUID_LL:
new_authdb_entry->duid.data.ll.hardware_type = client_duid->data.ll.hardware_type;
new_authdb_entry->duid.data.ll.content = IPDHCPS6_DUID_LL;
ipcom_memcpy (new_authdb_entry->duid.data.ll.link_addr,
client_duid->data.ll.link_addr, 6);
break;
case IPDHCPS6_DUID_EN: /* not yet implemented */
case IPDHCPS6_DUID_LLT: /* not yet implemented */
default:
/* Coverity defect fix for RESOURCE_LEAK */
ipcom_free( new_authdb_entry->secret.key);
ipcom_free (new_authdb_entry);
return IPCOM_ERR_FAILED;
}
if (IPCOM_SUCCESS != ipcom_hash_add (client_authkey_db, new_authdb_entry))
{
return IPCOM_ERR_FAILED;
}
return IPCOM_SUCCESS;
}
IP_GLOBAL Ip_err ipdhcps6_client_wants_auth (union Ipdhcps6_duid_data *client, int len)
{
Ip_u16 client_duid_content;
Ipdhcps6_authtrans_dbentry *client_dbentry = IP_NULL;
client_dbentry = (Ipdhcps6_authtrans_dbentry *)
ipcom_malloc (sizeof (struct Ipdhcps6_authtrans_dbentry));
if (IP_NULL == client_dbentry)
return IPCOM_ERR_NO_MEMORY;
client_duid_content = ip_ntohs (client->generic.content);
switch (client_duid_content)
{ case IPDHCPS6_DUID_LLT:
client_dbentry->duid.len = IPDHCPS6_DUID_LLT_ACTUALSIZE;
client_dbentry->duid.data.llt.content = IPDHCPS6_DUID_LLT;
client_dbentry->duid.data.llt.hardware_type = client->llt.hardware_type;
client_dbentry->duid.data.llt.time = client->llt.time;
ipcom_memcpy (client_dbentry->duid.data.llt.link_addr,
client->llt.link_addr, 6);
break;
case IPDHCPS6_DUID_EN:
/*
* FIXME
* using the duid union structure we have, we know we will have
* enough space to copy in the first 8 bytes of the enterprise
* ID. This may or may not be enough to be unique; we'll need
* to revisit this later. Look at "len" to see if we were given
* less than 8 bytes for the ID; if so, only copy the bytes
* given.
*/
client_dbentry->duid.len =
(Ip_u16)(len < IPDHCPS6_DUID_EN_ACTUALSIZE ?
len : IPDHCPS6_DUID_EN_ACTUALSIZE);
client_dbentry->duid.data.en.content = IPDHCPS6_DUID_EN;
client_dbentry->duid.data.en.enterprise_number_1 =
client->en.enterprise_number_1;
client_dbentry->duid.data.en.enterprise_number_2 =
client->en.enterprise_number_2;
ipcom_memcpy (client_dbentry->duid.data.en.id,
client->en.id, (Ip_size_t)(8 - (IPDHCPS6_DUID_EN_ACTUALSIZE - len)));
break;
case IPDHCPS6_DUID_LL:
client_dbentry->duid.len = IPDHCPS6_DUID_LL_ACTUALSIZE;
client_dbentry->duid.data.ll.content = IPDHCPS6_DUID_LL;
client_dbentry->duid.data.ll.hardware_type = client->ll.hardware_type;
ipcom_memcpy (client_dbentry->duid.data.ll.link_addr,
client->ll.link_addr, 6);
break;
default:
break;
}
/*
* set replay counters
*/
client_dbentry->server_replay1 = 0xdeadbeef;
client_dbentry->server_replay2 = 0x0;
client_dbentry->client_replay1 = 0x0;
client_dbentry->client_replay2 = 0x0;
if (IPCOM_SUCCESS != ipcom_hash_add (client_transaction_db, client_dbentry))
return IPCOM_ERR_FAILED;
return IPCOM_SUCCESS;
}
IP_GLOBAL Ip_err ipdhcps6_client_no_auth (union Ipdhcps6_duid_data *client, int len)
{
Ip_u16 client_duid_content;
Ipdhcps6_duid client_dbkey;
Ipdhcps6_authkey_dbentry *client_dbobj = IP_NULL;
client_duid_content = ip_ntohs (client->generic.content);
switch (client_duid_content)
{ case IPDHCPS6_DUID_LLT:
client_dbkey.len = IPDHCPS6_DUID_LLT_ACTUALSIZE;
client_dbkey.data.llt.content = IPDHCPS6_DUID_LLT;
client_dbkey.data.llt.hardware_type = client->llt.hardware_type;
client_dbkey.data.llt.time = client->llt.time;
ipcom_memcpy (client_dbkey.data.llt.link_addr,
client->llt.link_addr, 6);
break;
case IPDHCPS6_DUID_EN:
/*
* FIXME
* using the duid union structure we have, we know we will have
* enough space to copy in the first 8 bytes of the enterprise
* ID. This may or may not be enough to be unique; we'll need
* to revisit this later. Look at "len" to see if we were given
* less than 8 bytes for the ID; if so, only copy the bytes
* given.
*/
client_dbkey.len =
(Ip_u16)(len < IPDHCPS6_DUID_EN_ACTUALSIZE ?
len : IPDHCPS6_DUID_EN_ACTUALSIZE);
client_dbkey.data.en.content = IPDHCPS6_DUID_EN;
client_dbkey.data.en.enterprise_number_1 =
client->en.enterprise_number_1;
client_dbkey.data.en.enterprise_number_2 =
client->en.enterprise_number_2;
ipcom_memcpy (client_dbkey.data.en.id,
client->en.id, (Ip_size_t)(8 - (IPDHCPS6_DUID_EN_ACTUALSIZE - len)));
break;
case IPDHCPS6_DUID_LL:
client_dbkey.len = IPDHCPS6_DUID_LL_ACTUALSIZE;
client_dbkey.data.ll.content = IPDHCPS6_DUID_LL;
client_dbkey.data.ll.hardware_type = client->ll.hardware_type;
ipcom_memcpy (client_dbkey.data.ll.link_addr,
client->ll.link_addr, 6);
break;
default:
return IPCOM_ERR_FAILED;
}
client_dbobj = ipcom_hash_get (client_transaction_db, &client_dbkey);
if (IP_NULL == client_dbobj)
{
return IPCOM_SUCCESS;
}
else
{
ipcom_hash_remove (client_transaction_db, client_dbobj);
return IPCOM_SUCCESS;
}
}
IP_GLOBAL Ipdhcps6_authtrans_dbentry *
ipdhcps6_client_requested_auth (union Ipdhcps6_duid_data *client, int len)
{
Ip_u16 client_duid_content;
Ipdhcps6_duid client_dbkey;
Ipdhcps6_authtrans_dbentry *client_dbobj = IP_NULL;
client_duid_content = ip_ntohs (client->generic.content);
switch (client_duid_content)
{ case IPDHCPS6_DUID_LLT:
client_dbkey.len = IPDHCPS6_DUID_LLT_ACTUALSIZE;
client_dbkey.data.llt.content = IPDHCPS6_DUID_LLT;
client_dbkey.data.llt.hardware_type = client->llt.hardware_type;
client_dbkey.data.llt.time = client->llt.time;
ipcom_memcpy (client_dbkey.data.llt.link_addr,
client->llt.link_addr, 6);
break;
case IPDHCPS6_DUID_EN:
/*
* FIXME
* using the duid union structure we have, we know we will have
* enough space to copy in the first 8 bytes of the enterprise
* ID. This may or may not be enough to be unique; we'll need
* to revisit this later. Look at "len" to see if we were given
* less than 8 bytes for the ID; if so, only copy the bytes
* given.
*/
client_dbkey.len =
(Ip_u16)(len < IPDHCPS6_DUID_EN_ACTUALSIZE ?
len : IPDHCPS6_DUID_EN_ACTUALSIZE);
client_dbkey.data.en.content = IPDHCPS6_DUID_EN;
client_dbkey.data.en.enterprise_number_1 =
client->en.enterprise_number_1;
client_dbkey.data.en.enterprise_number_2 =
client->en.enterprise_number_2;
ipcom_memcpy (client_dbkey.data.en.id,
client->en.id, (Ip_size_t)(8 - (IPDHCPS6_DUID_EN_ACTUALSIZE - len)));
break;
case IPDHCPS6_DUID_LL:
client_dbkey.len = IPDHCPS6_DUID_LL_ACTUALSIZE;
client_dbkey.data.ll.content = IPDHCPS6_DUID_LL;
client_dbkey.data.ll.hardware_type = client->ll.hardware_type;
ipcom_memcpy (client_dbkey.data.ll.link_addr,
client->ll.link_addr, 6);
break;
default:
/* invalid DUID type; ignore it and return failure */
return IP_NULL;
}
client_dbobj = ipcom_hash_get (client_transaction_db, &client_dbkey);
if (IP_NULL == client_dbobj)
return IP_NULL;
return client_dbobj;
}
#define MAX_IPDHCPV6_AUTH_KEY_SIZE 128
IP_STATIC int authKeyInitialized = 0;
IP_STATIC int authRealmInitialized = 0;
IP_STATIC Ip_u8 authKeyFromSysVars [256];
IP_STATIC Ip_size_t authKeyLenFromSysVars = 0;
IP_STATIC Ip_u8 authKey [128];
IP_STATIC Ip_size_t authKeyLen = 0;
IP_STATIC Ip_u8 authRealmFromSysVars [128];
IP_STATIC Ip_size_t authRealmLenFromSysVars = 0;
IP_STATIC Ip_err ipdhcps6_set_default_auth_key_from_sysvars (void)
{
authKeyLenFromSysVars = sizeof (authKeyFromSysVars);
(void)ipcom_sysvar_get("ipdhcps6.authkey", (char *) authKeyFromSysVars,
&authKeyLenFromSysVars);
/*
* check if the value we read is a valid hex key; convert to
* a key buffer.
*/
if (ipdhcps6_check_is_hex_string ((char *) authKeyFromSysVars))
{
/* we need at least 4 characters to proceed here; "0x--" or more */
if (authKeyLenFromSysVars >= 4)
{ char *kptr = (char *) authKeyFromSysVars;
kptr += 2; /* get past leading "0x" */
authKeyLen = (authKeyLenFromSysVars - 2) / 2;
if (! ipdhcps6_cvt_hex_to_membuf (kptr, authKey, (int)authKeyLen) )
{ authKeyLen = 0;
return IPCOM_ERR_FAILED;
}
}
}
else
{
authKeyLen = 0;
return IPCOM_ERR_FAILED;
}
authKeyInitialized = 1;
return IPCOM_SUCCESS;
}
IP_GLOBAL Ip_err ipdhcps6_set_default_auth_key (char *authkey)
{
Ip_size_t auth_key_len;
auth_key_len = strlen (authkey);
if (auth_key_len > ((MAX_IPDHCPV6_AUTH_KEY_SIZE + 1) * 2))
{ return IPCOM_ERR_FAILED; /* given key is too large */
}
/*
* check if the value we read is a valid hex key; convert to
* a key buffer.
*/
if (ipdhcps6_check_is_hex_string (authkey))
{
/* we need at least 4 characters to proceed here; "0x--" or more */
if (auth_key_len >= 4)
{ char *kptr = authkey;
kptr += 2; /* get past leading "0x" */
authKeyLen = (auth_key_len - 2) / 2;
if (! ipdhcps6_cvt_hex_to_membuf (kptr, authKey, (int)authKeyLen) )
{ authKeyLen = 0;
return IPCOM_ERR_FAILED;
}
}
}
else
{
authKeyLen = 0;
return IPCOM_ERR_FAILED;
}
authKeyInitialized = 1;
return IPCOM_SUCCESS;
}
IP_GLOBAL Ip_err ipdhcps6_get_default_auth_key (Ip_size_t *len, Ip_u8 **key)
{
if (authKeyInitialized)
{
*len = authKeyLen;
*key = authKey;
return IPCOM_SUCCESS;
}
else
{
if (IPCOM_SUCCESS == ipdhcps6_set_default_auth_key_from_sysvars ())
{
*len = authKeyLen;
*key = authKey;
return IPCOM_SUCCESS;
}
}
*key = IP_NULL;
*len = 0;
return IPCOM_ERR_FAILED;
}
IP_STATIC Ip_err ipdhcps6_set_auth_realm_from_sysvars ()
{
authRealmLenFromSysVars = sizeof (authRealmFromSysVars);
if (ipcom_sysvar_get("ipdhcps6.authrealm", (char *) authRealmFromSysVars,
&authRealmLenFromSysVars) == IP_NULL)
{
/* Don't set it if we dont got it */
authRealmLenFromSysVars = 0;
}
if (authRealmLenFromSysVars > 0)
{
authRealmInitialized = 1;
return IPCOM_SUCCESS;
}
return IPCOM_ERR_FAILED;
}
IP_GLOBAL Ip_err ipdhcps6_set_auth_realm (char *auth_realm)
{
Ip_size_t realm_len;
authRealmInitialized = 0;
realm_len = strlen (auth_realm);
if ((unsigned)realm_len > (sizeof (authRealmFromSysVars) - 1))
{ /* passed in realm is too large. */
return IPCOM_ERR_FAILED;
}
strncpy ((char *) authRealmFromSysVars, auth_realm, realm_len);
authRealmFromSysVars [realm_len] = '\0';
authRealmLenFromSysVars = realm_len;
authRealmInitialized = 1;
return IPCOM_SUCCESS;
}
IP_GLOBAL Ip_err ipdhcps6_get_auth_realm (Ip_size_t *len, Ip_u8 **realm)
{
if (authRealmInitialized)
{ *len = authRealmLenFromSysVars;
*realm = authRealmFromSysVars;
return IPCOM_SUCCESS;
}
else
{ if (IPCOM_SUCCESS == ipdhcps6_set_auth_realm_from_sysvars ())
{
*len = authRealmLenFromSysVars;
*realm = authRealmFromSysVars;
return IPCOM_SUCCESS;
}
}
*len = 0;
return IPCOM_ERR_FAILED;
}
IP_GLOBAL void ipdhcps6_authdb_init (void)
{
client_authkey_db = ipdhcps6_authdb_hash_create ();
client_transaction_db = ipdhcps6_authtrans_hash_create ();
}
IP_GLOBAL Ip_err ipdhcps6_find_key_for_client (union Ipdhcps6_duid_data *client,
int duid_len,
Ip_u8 **key, Ip_size_t *key_len)
{
Ip_u16 client_duid_content;
Ipdhcps6_duid client_dbkey;
Ipdhcps6_authkey_dbentry *client_dbobj = IP_NULL;
client_duid_content = ip_ntohs (client->generic.content);
switch (client_duid_content)
{ case IPDHCPS6_DUID_LLT:
client_dbkey.len = IPDHCPS6_DUID_LL_ACTUALSIZE;
client_dbkey.data.ll.content = IPDHCPS6_DUID_LL;
client_dbkey.data.ll.hardware_type = client->llt.hardware_type;
ipcom_memcpy (client_dbkey.data.ll.link_addr,
client->llt.link_addr, 6);
break;
case IPDHCPS6_DUID_EN:
/*
* FIXME
* using the duid union structure we have, we know we will have
* enough space to copy in the first 8 bytes of the enterprise
* ID. This may or may not be enough to be unique; we'll need
* to revisit this later. Look at "len" to see if we were given
* less than 8 bytes for the ID; if so, only copy the bytes
* given.
*/
client_dbkey.len =
(Ip_u16)(duid_len < IPDHCPS6_DUID_EN_ACTUALSIZE ?
duid_len : IPDHCPS6_DUID_EN_ACTUALSIZE);
client_dbkey.data.en.content = IPDHCPS6_DUID_EN;
client_dbkey.data.en.enterprise_number_1 =
client->en.enterprise_number_1;
client_dbkey.data.en.enterprise_number_2 =
client->en.enterprise_number_2;
ipcom_memcpy (client_dbkey.data.en.id,
client->en.id, (Ip_size_t)(8 - (IPDHCPS6_DUID_EN_ACTUALSIZE - duid_len)));
break;
case IPDHCPS6_DUID_LL:
client_dbkey.len = IPDHCPS6_DUID_LL_ACTUALSIZE;
client_dbkey.data.ll.content = IPDHCPS6_DUID_LL;
client_dbkey.data.ll.hardware_type = client->ll.hardware_type;
ipcom_memcpy (client_dbkey.data.ll.link_addr,
client->ll.link_addr, 6);
break;
default:
return IPCOM_ERR_FAILED;
}
client_dbobj = ipcom_hash_get (client_authkey_db, &client_dbkey);
if (IP_NULL == client_dbobj)
{
/* use default system auth key */
return IPCOM_ERR_FAILED;
}
else
{
/* use client specific key */
*key_len = (Ip_size_t)client_dbobj->secret.len;
*key = client_dbobj->secret.key;
return IPCOM_SUCCESS;
}
}
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/