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

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
****************************************************************************
*/