1414 lines
42 KiB
C
1414 lines
42 KiB
C
|
|
/*
|
|
******************************************************************************
|
|
* INTERPEAK SOURCE FILE
|
|
*
|
|
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipdhcpc6_attr.c,v $ $Revision: 1.22.16.2 $
|
|
* $Source: /home/interpeak/CVSRoot/ipdhcpc6/src/ipdhcpc6_attr.c,v $
|
|
* $Author: fguo $
|
|
* $State: Exp $ $Locker: $
|
|
*
|
|
* Copyright 2000-2007 Interpeak AB (http://www.interpeak.se). All rights reserved.
|
|
* Design and implementation by Joel Hortelius <joel.hortelis@interpeak.se>
|
|
******************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 1 DESCRIPTION
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 2 CONFIGURATION
|
|
****************************************************************************
|
|
*/
|
|
|
|
#include "ipdhcpc6_config.h"
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 3 INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
#define IPCOM_USE_CLIB_PROTO
|
|
#include <ipcom_clib.h>
|
|
#include <ipcom_sock.h>
|
|
#include <ipcom_sock6.h>
|
|
#include <ipcom_list.h>
|
|
#include <ipcom_hash.h>
|
|
#include <ipcom_syslog.h>
|
|
#include <ipcom_err.h>
|
|
#include <ipcom_tmo2.h>
|
|
|
|
#include "ipdhcpc6.h"
|
|
#include "ipdhcpc6_h.h"
|
|
#include "ipdhcpc6_msg.h"
|
|
#include "ipdhcpc6_if.h"
|
|
#include "ipdhcpc6_ia.h"
|
|
#include "ipdhcpc6_attr.h"
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 4 DEFINES
|
|
****************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 5 TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
typedef struct Ipdhcpc6_attr_pargs
|
|
{
|
|
void *obj;
|
|
Ip_u32 mask;
|
|
} Ipdhcpc6_attr_pargs_t;
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 6 EXTERN PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 7 LOCAL PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 8 DATA
|
|
****************************************************************************
|
|
*/
|
|
|
|
char *ipdhcpc6_attr_if_link_state_name[] =
|
|
{
|
|
"uninitialized",
|
|
"detached",
|
|
"down",
|
|
"up"
|
|
};
|
|
|
|
char *ipdhcpc6_attr_mode_name[] =
|
|
{
|
|
"<invalid>",
|
|
"disabled",
|
|
"enabled",
|
|
"automatic"
|
|
};
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 9 STATIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_binding_attr
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipdhcpc6_attr_binding_attr(void *bobjp,
|
|
Ipdhcpc6_tagcomm_tag_t *tag)
|
|
{
|
|
Ipdhcpc6_attr_binding_t *bobj = bobjp;
|
|
|
|
switch (tag->tag)
|
|
{
|
|
case IPDHCPC6_IA_ATTR_ADDRESS:
|
|
ipdhcpc6_tagcomm_tag_in6_addr(tag, &bobj->prefix.addr);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_BINDING_PREFIX_PLEN:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &bobj->prefix.plen);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_BINDING_PREFIX_PREFERRED:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &bobj->preferred);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_BINDING_PREFIX_VALID:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &bobj->valid);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_BINDING_PREFIX_STATUS:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &bobj->status);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_TIMESTAMP:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &bobj->timestamp);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_ia_state_attr
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipdhcpc6_attr_ia_state_attr(void *bobjp,
|
|
Ipdhcpc6_tagcomm_tag_t *tag)
|
|
{
|
|
Ipdhcpc6_attr_ia_state_t *state = bobjp;
|
|
|
|
switch (tag->tag)
|
|
{
|
|
case IPDHCPC6_IA_ATTR_STATE_ACTION:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &state->action);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_STATE_STATUS:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &state->state);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_TIMESTAMP:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &state->timestamp);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_ia_state_parse
|
|
*===========================================================================
|
|
* Description: Parse an state object
|
|
* Parameters: tag - The tag.
|
|
* state - Where to store the state.
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC void
|
|
ipdhcpc6_attr_ia_state_parse(Ipdhcpc6_tagcomm_tag_t *tag,
|
|
Ipdhcpc6_attr_ia_state_t *state)
|
|
{
|
|
ipdhcpc6_tagcomm_parse_attributes(ipdhcpc6_attr_ia_state_attr, tag, state);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_ia_state_attr
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipdhcpc6_attr_ia_history_attr(void *bobjp,
|
|
Ipdhcpc6_tagcomm_tag_t *tag)
|
|
{
|
|
Ipdhcpc6_attr_array_t *array = bobjp;
|
|
Ipdhcpc6_attr_ia_state_t state;
|
|
|
|
switch (tag->tag)
|
|
{
|
|
case IPDHCPC6_IA_OBJECT_STATE:
|
|
ipdhcpc6_attr_ia_state_parse(tag, &state);
|
|
ipdhcpc6_attr_array_add(array, &state, sizeof(state));
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_ia_history_parse
|
|
*===========================================================================
|
|
* Description: Parse an state object
|
|
* Parameters: tag - The tag.
|
|
* array - Where to store the history
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC void
|
|
ipdhcpc6_attr_ia_history_parse(Ipdhcpc6_tagcomm_tag_t *tag,
|
|
Ipdhcpc6_attr_array_t *array)
|
|
{
|
|
ipdhcpc6_tagcomm_parse_objects(ipdhcpc6_attr_ia_history_attr, tag, array);
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_ia_attr
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipdhcpc6_attr_ia_attr(void *pargsp,
|
|
Ipdhcpc6_tagcomm_tag_t *tag)
|
|
{
|
|
Ipdhcpc6_attr_pargs_t *pargs = pargsp;
|
|
Ipdhcpc6_attr_ia_t *iaobj = pargs->obj;
|
|
Ipdhcpc6_attr_binding_t *bobj = IP_NULL;
|
|
|
|
switch (tag->tag)
|
|
{
|
|
/* IDENTITIES */
|
|
case IPDHCPC6_IA_IDENT_IA_IANAME:
|
|
if (ipdhcpc6_tagcomm_tag_string(tag, &iaobj->ianame))
|
|
iaobj->ianame = ipcom_strdup(iaobj->ianame);
|
|
break;
|
|
case IPDHCPC6_IA_IDENT_IA_IAID:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &iaobj->iaid);
|
|
break;
|
|
case IPDHCPC6_IA_IDENT_IA_IATYPE:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &iaobj->iatype);
|
|
break;
|
|
|
|
/* ATTRIBUTES */
|
|
case IPDHCPC6_IA_ATTR_IA_T1:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &iaobj->bindings.T1);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_IA_T2:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &iaobj->bindings.T2);
|
|
break;
|
|
|
|
case IPDHCPC6_IA_ATTR_TIMESTAMP:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &iaobj->bindings.timestamp);
|
|
break;
|
|
|
|
case IPDHCPC6_IA_ATTR_IA_T1_HINT:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &iaobj->hints.T1);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_IA_T2_HINT:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &iaobj->hints.T2);
|
|
break;
|
|
|
|
|
|
/* OBJECTS */
|
|
case IPDHCPC6_IA_OBJECT_STATE:
|
|
ipdhcpc6_attr_ia_state_parse(tag, &iaobj->state);
|
|
break;
|
|
case IPDHCPC6_IA_OBJECT_HISTORY:
|
|
ipdhcpc6_attr_ia_history_parse(tag, &iaobj->history);
|
|
break;
|
|
case IPDHCPC6_IA_OBJECT_SERVER:
|
|
ipdhcpc6_attr_if_server_free(&iaobj->router);
|
|
iaobj->router = ipdhcpc6_attr_if_server_parse(tag, pargs->mask);
|
|
break;
|
|
case IPDHCPC6_IA_OBJECT_BINDING_HINT:
|
|
bobj = ipdhcpc6_attr_binding_parse(tag);
|
|
if (bobj)
|
|
ipdhcpc6_attr_array_add(&iaobj->hints.binding, bobj, 0);
|
|
break;
|
|
|
|
case IPDHCPC6_IA_OBJECT_BINDING:
|
|
bobj = ipdhcpc6_attr_binding_parse(tag);
|
|
if (bobj)
|
|
ipdhcpc6_attr_array_add(&iaobj->bindings.binding, bobj, 0);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_if_config_attr
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipdhcpc6_attr_if_config_attr(void *pargsp,
|
|
Ipdhcpc6_tagcomm_tag_t *tag)
|
|
{
|
|
Ipdhcpc6_attr_pargs_t *pargs = pargsp;
|
|
Ipdhcpc6_attr_if_config_t *ifconfig = pargs->obj;
|
|
|
|
switch (tag->tag)
|
|
{
|
|
/* IDENTITIES */
|
|
|
|
/* ATTRIBUTES */
|
|
case IPDHCPC6_IA_ATTR_IF_CONFIG_RAPID_COMMIT:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &ifconfig->rapid_commit);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_IF_CONFIG_INFO_ONLY:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &ifconfig->information_only);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_IF_CONFIG_DNS:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &ifconfig->dns);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_IF_CONFIG_SNTP:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &ifconfig->sntp);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_IF_CONFIG_INFO_REFRESH:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &ifconfig->info_refresh);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_IF_CONFIG_SIP:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &ifconfig->sip);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_IF_CONFIG_FQDN:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &ifconfig->fqdn.fqdn);
|
|
break;
|
|
/* OBJECTS */
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_if_automatic_attr
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipdhcpc6_attr_if_automatic_attr(void *pargsp,
|
|
Ipdhcpc6_tagcomm_tag_t *tag)
|
|
{
|
|
Ipdhcpc6_attr_pargs_t *pargs = pargsp;
|
|
Ipdhcpc6_attr_if_automatic_t *ifauto = pargs->obj;
|
|
Ipdhcpc6_attr_if_server_t *ifsrv;
|
|
|
|
switch (tag->tag)
|
|
{
|
|
/* IDENTITIES */
|
|
|
|
/* ATTRIBUTES */
|
|
case IPDHCPC6_IA_OBJECT_SERVER:
|
|
ifsrv = ipdhcpc6_attr_if_server_parse(tag, pargs->mask);
|
|
if (ifsrv)
|
|
{
|
|
ipcom_memcpy(&ifauto->rtr, &ifsrv->address, sizeof(ifauto->rtr));
|
|
ipdhcpc6_attr_if_server_free(&ifsrv);
|
|
}
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_IF_AUTOMATIC_MANAGED:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &ifauto->runtime.managed);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_IF_AUTOMATIC_OTHER:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &ifauto->runtime.other);
|
|
break;
|
|
|
|
/* OBJECTS */
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_if_server_attr
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipdhcpc6_attr_if_server_attr(void *pargsp,
|
|
Ipdhcpc6_tagcomm_tag_t *tag)
|
|
{
|
|
Ipdhcpc6_attr_pargs_t *pargs = pargsp;
|
|
Ipdhcpc6_attr_if_server_t *ifsrv = pargs->obj;
|
|
struct Ip_in6_addr addr;
|
|
char *str;
|
|
|
|
switch (tag->tag)
|
|
{
|
|
/* IDENTITIES */
|
|
case IPDHCPC6_IA_IDENT_DUID:
|
|
if (IPDHCPC6_TAGCOMM_TAG_SIZE(tag) != 0)
|
|
{
|
|
ipdhcpc6_util_free(&ifsrv->id_vector);
|
|
ifsrv->id_size = IPDHCPC6_TAGCOMM_TAG_SIZE(tag);
|
|
ifsrv->id_vector = ipcom_malloc(ifsrv->id_size);
|
|
ipcom_memcpy(ifsrv->id_vector,
|
|
IPDHCPC6_TAGCOMM_TAG_DATA(tag),
|
|
ifsrv->id_size);
|
|
}
|
|
break;
|
|
/* ATTRIBUTES */
|
|
case IPDHCPC6_IA_ATTR_ADDRESS:
|
|
ipdhcpc6_tagcomm_tag_in6_addr(tag, &ifsrv->address);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_SERVER_UNICAST:
|
|
ipdhcpc6_tagcomm_tag_in6_addr(tag, &ifsrv->unicast);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_SERVER_INFO_REFRESH:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &ifsrv->info_refresh);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_SERVER_DNS_SERVER:
|
|
ipdhcpc6_tagcomm_tag_in6_addr(tag, &addr);
|
|
ipdhcpc6_attr_array_add(&ifsrv->dns, &addr, sizeof(addr));
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_SERVER_SNTP_SERVER:
|
|
ipdhcpc6_tagcomm_tag_in6_addr(tag, &addr);
|
|
ipdhcpc6_attr_array_add(&ifsrv->sntp, &addr, sizeof(addr));
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_SERVER_DOMAIN_LIST:
|
|
if (ipdhcpc6_tagcomm_tag_string(tag, &str))
|
|
ipdhcpc6_attr_array_add(&ifsrv->domain, str, ipcom_strlen(str) + 1);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_SERVER_SIP_D:
|
|
if (ipdhcpc6_tagcomm_tag_string(tag, &str))
|
|
ipdhcpc6_attr_array_add(&ifsrv->sip_d, str, ipcom_strlen(str) + 1);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_SERVER_SIP_A:
|
|
if (ipdhcpc6_tagcomm_tag_in6_addr(tag, &addr))
|
|
ipdhcpc6_attr_array_add(&ifsrv->sip_a, &addr, sizeof(addr));
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_SERVER_FQDN:
|
|
if (ipdhcpc6_tagcomm_tag_string(tag, &str))
|
|
ipdhcpc6_attr_array_add(&ifsrv->fqdn, str, ipcom_strlen(str) + 1);
|
|
break;
|
|
|
|
/* OBJECTS */
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_if_attr
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipdhcpc6_attr_if_attr(void *pargsp,
|
|
Ipdhcpc6_tagcomm_tag_t *tag)
|
|
{
|
|
Ipdhcpc6_attr_pargs_t *pargs = pargsp;
|
|
Ipdhcpc6_attr_if_t *ifobj = pargs->obj;
|
|
Ipdhcpc6_attr_ia_t *iaobj = IP_NULL;
|
|
Ipdhcpc6_attr_if_server_t *ifsrv;
|
|
|
|
switch (tag->tag)
|
|
{
|
|
/* IDENTITITIES */
|
|
case IPDHCPC6_IA_IDENT_NAME:
|
|
if (ipdhcpc6_tagcomm_tag_string(tag, &ifobj->ifname))
|
|
ifobj->ifname = ipcom_strdup(ifobj->ifname);
|
|
break;
|
|
|
|
/* ATTRIBUTES */
|
|
case IPDHCPC6_IA_ATTR_IF_MODE:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &ifobj->mode);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_IF_LINK_STATE:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, &ifobj->state);
|
|
break;
|
|
case IPDHCPC6_IA_ATTR_IF_VR:
|
|
ipdhcpc6_tagcomm_tag_u32(tag, (Ip_u32 *)&ifobj->vr);
|
|
break;
|
|
|
|
/* OBJECTS */
|
|
case IPDHCPC6_IA_OBJECT_IF_CONFIG:
|
|
ipdhcpc6_attr_if_config_free(&ifobj->config);
|
|
ifobj->config = ipdhcpc6_attr_if_config_parse(tag, pargs->mask);
|
|
break;
|
|
case IPDHCPC6_IA_OBJECT_IF_AUTOMATIC:
|
|
ipdhcpc6_attr_if_automatic_free(&ifobj->automatic);
|
|
ifobj->automatic= ipdhcpc6_attr_if_automatic_parse(tag, pargs->mask);
|
|
break;
|
|
|
|
case IPDHCPC6_IA_OBJECT_IA:
|
|
iaobj = ipdhcpc6_attr_ia_parse(tag, pargs->mask);
|
|
if (iaobj)
|
|
ipdhcpc6_attr_array_add(&ifobj->ias, iaobj, 0);
|
|
break;
|
|
case IPDHCPC6_IA_OBJECT_SERVER:
|
|
ifsrv = ipdhcpc6_attr_if_server_parse(tag, pargs->mask);
|
|
if (ifsrv)
|
|
ipdhcpc6_attr_array_add(&ifobj->servers, ifsrv, 0);
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 10 GLOBAL FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_binding_parse
|
|
*===========================================================================
|
|
* Description: Parse an IPDHCPC6_IA_OBJECT_BINDING or
|
|
* IPDHCPC6_IA_OBJECT_BINDING_HINT tag.
|
|
* Parameters: tag - The tag.
|
|
* Returns: The binding object
|
|
*
|
|
*/
|
|
IP_GLOBAL Ipdhcpc6_attr_binding_t *
|
|
ipdhcpc6_attr_binding_parse(Ipdhcpc6_tagcomm_tag_t *tag)
|
|
{
|
|
Ipdhcpc6_attr_binding_t *bobj = ipcom_calloc(1, sizeof(*bobj));
|
|
|
|
if (bobj)
|
|
ipdhcpc6_tagcomm_parse_attributes(ipdhcpc6_attr_binding_attr, tag, bobj);
|
|
|
|
return bobj;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_binding_free
|
|
*===========================================================================
|
|
* Description: Free any resources previously allocated by parse.
|
|
* Parameters: bobjp - The binding object.
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_GLOBAL void
|
|
ipdhcpc6_attr_binding_free(Ipdhcpc6_attr_binding_t **bobjp)
|
|
{
|
|
Ipdhcpc6_attr_binding_t *bobj = *bobjp;
|
|
|
|
if (bobj)
|
|
{
|
|
ipdhcpc6_util_free(&bobj);
|
|
}
|
|
|
|
*bobjp = IP_NULL;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_ia_parse
|
|
*===========================================================================
|
|
* Description: Parse an IPDHCPC6_ATTR_IA_IF_IA_OBJECT tag.
|
|
* Parameters: tag - The tag.
|
|
* mask - The type of objects we'll parse; 0 = all.
|
|
* Returns: The identity association pointer with its associated BINDINGS.
|
|
*
|
|
*/
|
|
IP_GLOBAL Ipdhcpc6_attr_ia_t *
|
|
ipdhcpc6_attr_ia_parse(Ipdhcpc6_tagcomm_tag_t *tag,
|
|
Ip_u32 mask)
|
|
{
|
|
Ipdhcpc6_attr_ia_t *iaobj = ipcom_calloc(1, sizeof(*iaobj));
|
|
|
|
if (mask == 0)
|
|
mask = IPDHCPC6_TAGCOMM_TAG_MASK;
|
|
|
|
if (iaobj)
|
|
{
|
|
Ipdhcpc6_attr_pargs_t pargs;
|
|
|
|
pargs.mask = mask;
|
|
pargs.obj = iaobj;
|
|
|
|
iaobj->status = tag->status;
|
|
if (IP_BIT_ISSET(mask, IPDHCPC6_TAGCOMM_TAG_IDENTITY))
|
|
ipdhcpc6_tagcomm_parse_identities(ipdhcpc6_attr_ia_attr, tag, &pargs);
|
|
if (IP_BIT_ISSET(mask, IPDHCPC6_TAGCOMM_TAG_ATTRIBUTE))
|
|
ipdhcpc6_tagcomm_parse_attributes(ipdhcpc6_attr_ia_attr, tag, &pargs);
|
|
if (IP_BIT_ISSET(mask, IPDHCPC6_TAGCOMM_TAG_OBJECT))
|
|
ipdhcpc6_tagcomm_parse_objects(ipdhcpc6_attr_ia_attr, tag, &pargs);
|
|
}
|
|
|
|
return iaobj;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_ia_free
|
|
*===========================================================================
|
|
* Description: Free any resources previously allocated by parse. Will also
|
|
* free any bindings
|
|
* Parameters: iaobjp - The IA object.
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_GLOBAL void
|
|
ipdhcpc6_attr_ia_free(Ipdhcpc6_attr_ia_t **iaobjp)
|
|
{
|
|
Ipdhcpc6_attr_ia_t *iaobj = *iaobjp;
|
|
|
|
if (iaobj)
|
|
{
|
|
if (iaobj->ianame)
|
|
{
|
|
ipdhcpc6_util_free(&iaobj->ianame);
|
|
}
|
|
|
|
ipdhcpc6_attr_if_server_free(&iaobj->router);
|
|
ipdhcpc6_attr_array_free(&iaobj->history,
|
|
(Ipdhcpc6_attr_array_free_t)ipdhcpc6_util_free);
|
|
ipdhcpc6_attr_array_free(&iaobj->bindings.binding,
|
|
(Ipdhcpc6_attr_array_free_t)ipdhcpc6_attr_binding_free);
|
|
ipdhcpc6_attr_array_free(&iaobj->hints.binding,
|
|
(Ipdhcpc6_attr_array_free_t)ipdhcpc6_attr_binding_free);
|
|
ipdhcpc6_util_free(&iaobj);
|
|
}
|
|
|
|
*iaobjp = IP_NULL;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_if_automatic_parse
|
|
*===========================================================================
|
|
* Description: Parse an IPDHCPC6_IA_OBJECT_IF_AUTOMATIC tag.
|
|
* Parameters: tag - The tag.
|
|
* mask - The type of objects we'll parse; 0 = all.
|
|
* Returns: The interface config pointer
|
|
*
|
|
*/
|
|
IP_GLOBAL Ipdhcpc6_attr_if_automatic_t *
|
|
ipdhcpc6_attr_if_automatic_parse(Ipdhcpc6_tagcomm_tag_t *tag,
|
|
Ip_u32 mask)
|
|
{
|
|
Ipdhcpc6_attr_if_automatic_t *ifauto = ipcom_calloc(1, sizeof(*ifauto));
|
|
|
|
if (mask == 0)
|
|
mask = IPDHCPC6_TAGCOMM_TAG_MASK;
|
|
|
|
if (ifauto)
|
|
{
|
|
Ipdhcpc6_attr_pargs_t pargs;
|
|
|
|
pargs.mask = mask;
|
|
pargs.obj = ifauto;
|
|
|
|
if (IP_BIT_ISSET(mask, IPDHCPC6_TAGCOMM_TAG_IDENTITY))
|
|
ipdhcpc6_tagcomm_parse_identities(ipdhcpc6_attr_if_automatic_attr, tag, &pargs);
|
|
if (IP_BIT_ISSET(mask, IPDHCPC6_TAGCOMM_TAG_ATTRIBUTE))
|
|
ipdhcpc6_tagcomm_parse_attributes(ipdhcpc6_attr_if_automatic_attr, tag, &pargs);
|
|
if (IP_BIT_ISSET(mask, IPDHCPC6_TAGCOMM_TAG_OBJECT))
|
|
ipdhcpc6_tagcomm_parse_objects(ipdhcpc6_attr_if_automatic_attr, tag, &pargs);
|
|
}
|
|
|
|
return ifauto;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_if_automatic_free
|
|
*===========================================================================
|
|
* Description: Free any resources previously allocated by parse.
|
|
* Parameters: ifautop - The interface automatic object.
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_GLOBAL void
|
|
ipdhcpc6_attr_if_automatic_free(Ipdhcpc6_attr_if_automatic_t **ifautop)
|
|
{
|
|
Ipdhcpc6_attr_if_automatic_t *ifauto = *ifautop;
|
|
|
|
if (ifauto)
|
|
{
|
|
ipdhcpc6_util_free(&ifauto);
|
|
}
|
|
|
|
*ifautop = IP_NULL;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_if_server_parse
|
|
*===========================================================================
|
|
* Description: Parse an IPDHCPC6_IA_OBJECT_SERVER tag.
|
|
* Parameters: tag - The tag.
|
|
* mask - The type of objects we'll parse; 0 = all.
|
|
* Returns: The interface server pointer
|
|
*
|
|
*/
|
|
IP_GLOBAL Ipdhcpc6_attr_if_server_t *
|
|
ipdhcpc6_attr_if_server_parse(Ipdhcpc6_tagcomm_tag_t *tag,
|
|
Ip_u32 mask)
|
|
{
|
|
Ipdhcpc6_attr_if_server_t *ifsrv = ipcom_calloc(1, sizeof(*ifsrv));
|
|
|
|
if (mask == 0)
|
|
mask = IPDHCPC6_TAGCOMM_TAG_MASK;
|
|
|
|
if (ifsrv)
|
|
{
|
|
Ipdhcpc6_attr_pargs_t pargs;
|
|
|
|
pargs.mask = mask;
|
|
pargs.obj = ifsrv;
|
|
|
|
if (IP_BIT_ISSET(mask, IPDHCPC6_TAGCOMM_TAG_IDENTITY))
|
|
ipdhcpc6_tagcomm_parse_identities(ipdhcpc6_attr_if_server_attr, tag, &pargs);
|
|
if (IP_BIT_ISSET(mask, IPDHCPC6_TAGCOMM_TAG_ATTRIBUTE))
|
|
ipdhcpc6_tagcomm_parse_attributes(ipdhcpc6_attr_if_server_attr, tag, &pargs);
|
|
if (IP_BIT_ISSET(mask, IPDHCPC6_TAGCOMM_TAG_OBJECT))
|
|
ipdhcpc6_tagcomm_parse_objects(ipdhcpc6_attr_if_server_attr, tag, &pargs);
|
|
}
|
|
|
|
return ifsrv;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_if_server_free
|
|
*===========================================================================
|
|
* Description: Free any resources previously allocated by parse.
|
|
* Parameters: ifsrvp - The interface server object.
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_GLOBAL void
|
|
ipdhcpc6_attr_if_server_free(Ipdhcpc6_attr_if_server_t **ifsrvp)
|
|
{
|
|
Ipdhcpc6_attr_if_server_t *ifsrv = *ifsrvp;
|
|
|
|
if (ifsrv)
|
|
{
|
|
ipdhcpc6_attr_array_free(&ifsrv->dns,
|
|
(Ipdhcpc6_attr_array_free_t)ipdhcpc6_util_free);
|
|
ipdhcpc6_attr_array_free(&ifsrv->domain,
|
|
(Ipdhcpc6_attr_array_free_t)ipdhcpc6_util_free);
|
|
ipdhcpc6_attr_array_free(&ifsrv->sntp,
|
|
(Ipdhcpc6_attr_array_free_t)ipdhcpc6_util_free);
|
|
ipdhcpc6_attr_array_free(&ifsrv->sip_d,
|
|
(Ipdhcpc6_attr_array_free_t)ipdhcpc6_util_free);
|
|
ipdhcpc6_attr_array_free(&ifsrv->sip_a,
|
|
(Ipdhcpc6_attr_array_free_t)ipdhcpc6_util_free);
|
|
/*Free the fqdn stored before*/
|
|
ipdhcpc6_attr_array_free (&ifsrv->fqdn,
|
|
(Ipdhcpc6_attr_array_free_t)ipdhcpc6_util_free);
|
|
ipdhcpc6_util_free(&ifsrv->id_vector);
|
|
ipdhcpc6_util_free(&ifsrv);
|
|
}
|
|
|
|
*ifsrvp = IP_NULL;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_if_config_parse
|
|
*===========================================================================
|
|
* Description: Parse an IPDHCPC6_IA_OBJECT_IF_CONFIG tag.
|
|
* Parameters: tag - The tag.
|
|
* mask - The type of objects we'll parse; 0 = all.
|
|
* Returns: The interface config pointer
|
|
*
|
|
*/
|
|
IP_GLOBAL Ipdhcpc6_attr_if_config_t *
|
|
ipdhcpc6_attr_if_config_parse(Ipdhcpc6_tagcomm_tag_t *tag,
|
|
Ip_u32 mask)
|
|
{
|
|
Ipdhcpc6_attr_if_config_t *ifconfig = ipcom_calloc(1, sizeof(*ifconfig));
|
|
|
|
if (mask == 0)
|
|
mask = IPDHCPC6_TAGCOMM_TAG_MASK;
|
|
|
|
if (ifconfig)
|
|
{
|
|
Ipdhcpc6_attr_pargs_t pargs;
|
|
|
|
pargs.mask = mask;
|
|
pargs.obj = ifconfig;
|
|
|
|
if (IP_BIT_ISSET(mask, IPDHCPC6_TAGCOMM_TAG_IDENTITY))
|
|
ipdhcpc6_tagcomm_parse_identities(ipdhcpc6_attr_if_config_attr, tag, &pargs);
|
|
if (IP_BIT_ISSET(mask, IPDHCPC6_TAGCOMM_TAG_ATTRIBUTE))
|
|
ipdhcpc6_tagcomm_parse_attributes(ipdhcpc6_attr_if_config_attr, tag, &pargs);
|
|
if (IP_BIT_ISSET(mask, IPDHCPC6_TAGCOMM_TAG_OBJECT))
|
|
ipdhcpc6_tagcomm_parse_objects(ipdhcpc6_attr_if_config_attr, tag, &pargs);
|
|
}
|
|
|
|
return ifconfig;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_if_config_free
|
|
*===========================================================================
|
|
* Description: Free any resources previously allocated by parse.
|
|
* Parameters: ifconfigp - The interface config object.
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_GLOBAL void
|
|
ipdhcpc6_attr_if_config_free(Ipdhcpc6_attr_if_config_t **ifconfigp)
|
|
{
|
|
Ipdhcpc6_attr_if_config_t *ifconfig = *ifconfigp;
|
|
|
|
if (ifconfig)
|
|
{
|
|
ipdhcpc6_util_free(&ifconfig);
|
|
}
|
|
|
|
*ifconfigp = IP_NULL;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_if_parse
|
|
*===========================================================================
|
|
* Description: Parse an IPDHCPC6_ATTR_IA_IF_OBJECT tag.
|
|
* Parameters: tag - The tag.
|
|
* mask - The type of objects we'll parse; 0 = all.
|
|
* Returns: The interface pointer with its associated IA/BINDINGS.
|
|
*
|
|
*/
|
|
IP_GLOBAL Ipdhcpc6_attr_if_t *
|
|
ipdhcpc6_attr_if_parse(Ipdhcpc6_tagcomm_tag_t *tag,
|
|
Ip_u32 mask)
|
|
{
|
|
Ipdhcpc6_attr_if_t *ifobj = ipcom_calloc(1, sizeof(*ifobj));
|
|
|
|
if (mask == 0)
|
|
mask = IPDHCPC6_TAGCOMM_TAG_MASK;
|
|
|
|
if (ifobj)
|
|
{
|
|
Ipdhcpc6_attr_pargs_t pargs;
|
|
|
|
pargs.mask = mask;
|
|
pargs.obj = ifobj;
|
|
|
|
ifobj->status = tag->status;
|
|
if (IP_BIT_ISSET(mask, IPDHCPC6_TAGCOMM_TAG_IDENTITY))
|
|
ipdhcpc6_tagcomm_parse_identities(ipdhcpc6_attr_if_attr, tag, &pargs);
|
|
if (IP_BIT_ISSET(mask, IPDHCPC6_TAGCOMM_TAG_ATTRIBUTE))
|
|
ipdhcpc6_tagcomm_parse_attributes(ipdhcpc6_attr_if_attr, tag, &pargs);
|
|
if (IP_BIT_ISSET(mask, IPDHCPC6_TAGCOMM_TAG_OBJECT))
|
|
ipdhcpc6_tagcomm_parse_objects(ipdhcpc6_attr_if_attr, tag, &pargs);
|
|
}
|
|
|
|
return ifobj;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_if_free
|
|
*===========================================================================
|
|
* Description: Free any resources previously allocated by parse. Will also
|
|
* free any ias
|
|
* Parameters: ifobjp - The interface object.
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_GLOBAL void
|
|
ipdhcpc6_attr_if_free(Ipdhcpc6_attr_if_t **ifobjp)
|
|
{
|
|
Ipdhcpc6_attr_if_t *ifobj = *ifobjp;
|
|
|
|
if (ifobj)
|
|
{
|
|
ipdhcpc6_util_free(&ifobj->ifname);
|
|
|
|
ipdhcpc6_attr_if_automatic_free(&ifobj->automatic);
|
|
ipdhcpc6_attr_if_config_free(&ifobj->config);
|
|
|
|
ipdhcpc6_attr_array_free(&ifobj->ias,
|
|
(Ipdhcpc6_attr_array_free_t) ipdhcpc6_attr_ia_free);
|
|
ipdhcpc6_attr_array_free(&ifobj->servers,
|
|
(Ipdhcpc6_attr_array_free_t) ipdhcpc6_attr_if_server_free);
|
|
|
|
ipdhcpc6_util_free(&ifobj);
|
|
}
|
|
|
|
*ifobjp = IP_NULL;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_read
|
|
*===========================================================================
|
|
* Description: Read the number of bytes specified by rbuf
|
|
* Parameters: fd - The filedescriptor to read from
|
|
* rbuf - The read buffer
|
|
* block - Block until the entire command is read.
|
|
* Returns: The number of remaining bytes to read.
|
|
*
|
|
*/
|
|
IP_GLOBAL int
|
|
ipdhcpc6_attr_read(Ip_fd fd,
|
|
Ipdhcpc6_attr_readbuf_t *rbuf,
|
|
Ip_bool block)
|
|
{
|
|
do
|
|
{
|
|
int bytes;
|
|
|
|
/* Read it all? */
|
|
if (rbuf->read_size == rbuf->total_size)
|
|
return 0;
|
|
|
|
bytes = ipcom_recv(fd, &rbuf->buffer[rbuf->read_size], rbuf->total_size - rbuf->read_size, 0);
|
|
|
|
/* Failed? */
|
|
if (bytes <= 0)
|
|
return -1;
|
|
|
|
rbuf->read_size += bytes;
|
|
|
|
/* Only continue if they specified that we wait for it */
|
|
} while (block);
|
|
|
|
/* return remaining */
|
|
return (int)(rbuf->total_size - rbuf->read_size);
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_sendmsg
|
|
*===========================================================================
|
|
* Description: Send a message over fd
|
|
* Parameters: fd - File descriptor.
|
|
* buf - Pointer to buffer.
|
|
* Returns: IP_TRUE if successful.
|
|
*
|
|
*/
|
|
IP_GLOBAL Ip_bool
|
|
ipdhcpc6_attr_sendmsg(Ip_fd fd,
|
|
Ipdhcpc6_tagcomm_buffer_t *buf)
|
|
{
|
|
Ip_bool ret = IP_FALSE;
|
|
|
|
if (buf)
|
|
{
|
|
if (ipcom_send(fd, buf->head, buf->offset, 0) == buf->offset)
|
|
ret = IP_TRUE;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_recvhdr
|
|
*===========================================================================
|
|
* Description: Read the header of a command, and allocate the required
|
|
* buffer space.
|
|
* Parameters: fd - File descriptor
|
|
* rbuf - Read buffer.
|
|
* Returns: IP_TRUE if successful.
|
|
*
|
|
*/
|
|
IP_GLOBAL Ip_bool
|
|
ipdhcpc6_attr_recvhdr(Ip_fd fd,
|
|
Ipdhcpc6_attr_readbuf_t *rbuf)
|
|
{
|
|
Ipdhcpc6_tagcomm_tag_t tag;
|
|
Ipdhcpc6_tagcomm_tag_t *ptag;
|
|
|
|
ipcom_memset(rbuf, 0, sizeof(*rbuf));
|
|
|
|
rbuf->buffer = (Ip_u8 *)&tag;
|
|
rbuf->total_size = sizeof(tag);
|
|
|
|
/* Read the TAG header */
|
|
if (ipdhcpc6_attr_read(fd, rbuf, IP_TRUE) < 0 ||
|
|
tag.length < sizeof(tag))
|
|
{
|
|
rbuf->buffer = IP_NULL;
|
|
return IP_FALSE;
|
|
}
|
|
|
|
rbuf->total_size = tag.length + sizeof(tag);
|
|
rbuf->read_size = sizeof(tag) * 2;
|
|
rbuf->buffer = ipcom_malloc(rbuf->total_size + sizeof(tag));
|
|
if (rbuf->buffer == IP_NULL)
|
|
return IP_FALSE;
|
|
|
|
ptag = (Ipdhcpc6_tagcomm_tag_t *) rbuf->buffer;
|
|
ptag->length = (Ip_u16)rbuf->total_size;
|
|
ptag->tag = 0;
|
|
ptag->status = 0;
|
|
|
|
ipcom_memcpy(rbuf->buffer + sizeof(tag), &tag, sizeof(tag));
|
|
return IP_TRUE;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_recvmsg
|
|
*===========================================================================
|
|
* Description: Read a message. A buffer holding the entire message will
|
|
* be dynamically allocated on success.
|
|
* Parameters: fd - File descriptor.
|
|
* rbuf - Pointer to buffer pointer. Will hold the
|
|
* dynamically allocated buffer on success.
|
|
* Returns: IP_TRUE if successful.
|
|
*
|
|
*/
|
|
IP_GLOBAL Ip_bool
|
|
ipdhcpc6_attr_recvmsg(Ip_fd fd,
|
|
Ipdhcpc6_attr_readbuf_t *rbuf)
|
|
{
|
|
if (ipdhcpc6_attr_recvhdr(fd, rbuf) == IP_FALSE)
|
|
return IP_FALSE;
|
|
|
|
if (ipdhcpc6_attr_read(fd, rbuf, IP_TRUE) < 0)
|
|
{
|
|
ipdhcpc6_util_free(&rbuf->buffer);
|
|
return IP_FALSE;
|
|
}
|
|
|
|
return IP_TRUE;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_connect
|
|
*===========================================================================
|
|
* Description: Create a TCP connection to the DHCPv6 Client
|
|
* Parameters:
|
|
* Returns: A file descriptor if successful, IP_INVALID_SOCKET otherwise.
|
|
*
|
|
*/
|
|
IP_GLOBAL Ip_fd
|
|
ipdhcpc6_attr_connect(void)
|
|
{
|
|
Ip_fd fd;
|
|
struct Ip_sockaddr_in6 sin6;
|
|
|
|
/* Create the API socket */
|
|
fd = ipcom_socket(IP_AF_INET6, IP_SOCK_STREAM, IP_IPPROTO_TCP);
|
|
if (fd != IP_INVALID_SOCKET)
|
|
{
|
|
ipcom_memset(&sin6, 0, sizeof(sin6));
|
|
sin6.sin6_family = IP_AF_INET6;
|
|
sin6.sin6_len = sizeof(sin6);
|
|
sin6.sin6_port = ip_htons(IPDHCPC6_CLIENT_PORT);
|
|
sin6.sin6_addr = ip_in6addr_loopback;
|
|
|
|
/* Do connect */
|
|
if (ipcom_connect(fd, (struct Ip_sockaddr *)&sin6, sizeof(sin6)) < 0)
|
|
{
|
|
ipcom_socketclose(fd);
|
|
return IP_INVALID_SOCKET;
|
|
}
|
|
|
|
}
|
|
|
|
return fd;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_errno
|
|
*===========================================================================
|
|
* Description: Return human readable string representation for error
|
|
* Parameters: errcode - The errcode
|
|
* Returns: The human readable string
|
|
*
|
|
*/
|
|
IP_GLOBAL const char *
|
|
ipdhcpc6_attr_errno(Ip_u32 errcode)
|
|
{
|
|
switch (errcode)
|
|
{
|
|
case IPDHCPC6_TAGCOMM_STATUS_UNKNOWN_TAG:
|
|
return "unknown tag";
|
|
case IPDHCPC6_TAGCOMM_STATUS_PARSE_FAILED:
|
|
return "parse failed";
|
|
case IPDHCPC6_ATTR_TAG_STATUS_UNKNOWN_INTERFACE:
|
|
return "unknown interface";
|
|
case IPDHCPC6_ATTR_TAG_STATUS_UNKNOWN_IA:
|
|
return "unknown identity association (IA)";
|
|
default:
|
|
return "unknown error";
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_ia_status
|
|
*===========================================================================
|
|
* Description: Return the human readable name of the status
|
|
* Parameters: status - The status
|
|
* Returns: The human readable name
|
|
*
|
|
*/
|
|
IP_GLOBAL const char *
|
|
ipdhcpc6_attr_ia_status(Ip_u32 status)
|
|
{
|
|
switch (status)
|
|
{
|
|
case IPDHCPC6_IA_STATE_SOLICIT:
|
|
return "solicit";
|
|
case IPDHCPC6_IA_STATE_BOUND:
|
|
return "bound";
|
|
}
|
|
|
|
return "<unknown>";
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_ia_action
|
|
*===========================================================================
|
|
* Description: Return the human readable name of the action
|
|
* Parameters: action - The action
|
|
* Returns: The human readable name
|
|
*
|
|
*/
|
|
IP_GLOBAL const char *
|
|
ipdhcpc6_attr_ia_action(Ip_u32 action)
|
|
{
|
|
switch (action)
|
|
{
|
|
case IPDHCPC6_IA_ACTION_IDLE:
|
|
return "idle";
|
|
case IPDHCPC6_IA_ACTION_SOLICIT:
|
|
return "solicit";
|
|
case IPDHCPC6_IA_ACTION_REQUEST:
|
|
return "request";
|
|
case IPDHCPC6_IA_ACTION_RENEW:
|
|
return "renew";
|
|
case IPDHCPC6_IA_ACTION_REBIND:
|
|
case IPDHCPC6_IA_ACTION_REBINDCONF:
|
|
return "rebind";
|
|
case IPDHCPC6_IA_ACTION_CONFIRM:
|
|
return "confirm";
|
|
case IPDHCPC6_IA_ACTION_RELEASE:
|
|
return "release";
|
|
case IPDHCPC6_IA_ACTION_DECLINE:
|
|
return "decline";
|
|
case IPDHCPC6_IA_ACTION_SOLICITING:
|
|
return "soliciting";
|
|
case IPDHCPC6_IA_ACTION_REQUESTING:
|
|
return "requesting";
|
|
case IPDHCPC6_IA_ACTION_RENEWING:
|
|
return "renewing";
|
|
case IPDHCPC6_IA_ACTION_REBINDING:
|
|
case IPDHCPC6_IA_ACTION_REBINDCONFING:
|
|
return "rebinding";
|
|
case IPDHCPC6_IA_ACTION_CONFIRMING:
|
|
return "confirming";
|
|
case IPDHCPC6_IA_ACTION_RELEASING:
|
|
return "releasing";
|
|
case IPDHCPC6_IA_ACTION_DECLINEING:
|
|
return "declining";
|
|
}
|
|
|
|
return "<unknown>";
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_array_add
|
|
*===========================================================================
|
|
* Description: Add an element to an array; allocate the array or increase
|
|
* it if required.
|
|
* Parameters: array - Pointer to the array
|
|
* object - Object
|
|
* size - Size of object; if zero, don't copy. Store as is.
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_GLOBAL void
|
|
ipdhcpc6_attr_array_add(Ipdhcpc6_attr_array_t *array,
|
|
void *object,
|
|
Ip_size_t size)
|
|
{
|
|
Ip_u32 remain = array->size - array->num;
|
|
|
|
/* Increase the array size? */
|
|
if (remain == 0)
|
|
{
|
|
Ip_size_t nsize = IP_MAX(3, array->size) * 2;
|
|
void **narr = ipcom_calloc(nsize, sizeof(*narr));
|
|
|
|
if (narr == IP_NULL)
|
|
return;
|
|
|
|
if (array->num)
|
|
ipcom_memmove(narr, array->array, sizeof(void *) * array->num);
|
|
|
|
ipdhcpc6_util_free(&array->array);
|
|
array->array = narr;
|
|
array->size = (Ip_u32)nsize;
|
|
}
|
|
|
|
/* Do I want to copy the object? */
|
|
if (size)
|
|
{
|
|
void *nobj = ipcom_malloc(size);
|
|
if (nobj == IP_NULL)
|
|
return;
|
|
|
|
ipcom_memcpy(nobj, object, size);
|
|
object = nobj;
|
|
}
|
|
|
|
array->array[array->num++] = object;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_array_free
|
|
*===========================================================================
|
|
* Description: Free the array and its elements.
|
|
* Parameters: array - The array
|
|
* freefunc - Option function to invoke per element.
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_GLOBAL void
|
|
ipdhcpc6_attr_array_free(Ipdhcpc6_attr_array_t *array,
|
|
Ipdhcpc6_attr_array_free_t freefunc)
|
|
{
|
|
if (array->size)
|
|
{
|
|
if (freefunc)
|
|
{
|
|
int i;
|
|
for (i = 0; i < (int)array->num; i++)
|
|
(*freefunc) (&array->array[i]);
|
|
}
|
|
|
|
ipdhcpc6_util_free(&array->array);
|
|
array->size = 0;
|
|
array->num = 0;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_array_remove
|
|
*===========================================================================
|
|
* Description: Remove a particular element from the array
|
|
* Parameters: array - The array
|
|
* obj - The object
|
|
* freefunc - The free function.
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_GLOBAL void
|
|
ipdhcpc6_attr_array_remove(Ipdhcpc6_attr_array_t *array,
|
|
void *obj,
|
|
Ipdhcpc6_attr_array_free_t freefunc)
|
|
{
|
|
int i;
|
|
for (i = 0; i < (int)array->num; i++)
|
|
{
|
|
if (array->array[i] == obj)
|
|
{
|
|
array->num--;
|
|
if (((int)array->num - i) > 0)
|
|
ipcom_memmove(&array->array[i], &array->array[i + 1], (array->num - i) * sizeof(obj));
|
|
|
|
if (freefunc)
|
|
(*freefunc) (&obj);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_server_set_unicast
|
|
*===========================================================================
|
|
* Description: Set a unicast address
|
|
* Parameters: srv - The server attributes
|
|
* addr - Address
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_GLOBAL void
|
|
ipdhcpc6_attr_server_set_unicast(Ipdhcpc6_attr_if_server_t *srv,
|
|
const struct Ip_in6_addr *addr)
|
|
{
|
|
if (addr == IP_NULL)
|
|
addr = &ip_in6addr_any;
|
|
ipcom_memcpy(&srv->unicast, addr, sizeof(*addr));
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_attr_server_unicast
|
|
*===========================================================================
|
|
* Description: Returns the unicast address for a server
|
|
* Parameters: srv - The server attributes
|
|
* Returns: The unicast address if it exists.
|
|
*
|
|
*/
|
|
IP_GLOBAL const struct Ip_in6_addr *
|
|
ipdhcpc6_attr_server_unicast(Ipdhcpc6_attr_if_server_t *srv)
|
|
{
|
|
if (IP_IN6_ARE_ADDR_EQUAL(&srv->unicast, &ip_in6addr_any))
|
|
return IP_NULL;
|
|
|
|
return &srv->unicast;
|
|
}
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 11 PUBLIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|