378 lines
11 KiB
C
378 lines
11 KiB
C
|
|
/*
|
|
******************************************************************************
|
|
* INTERPEAK SOURCE FILE
|
|
*
|
|
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipdhcpc6_info.c,v $ $Revision: 1.3.56.2 $
|
|
* $Source: /home/interpeak/CVSRoot/ipdhcpc6/src/ipdhcpc6_info.c,v $
|
|
* $Author: ulf $
|
|
* $State: Exp $ $Locker: $
|
|
*
|
|
* INTERPEAK_COPYRIGHT_STRING
|
|
* 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_syslog.h>
|
|
#include <ipcom_err.h>
|
|
#include <ipcom_tmo2.h>
|
|
#include <ipcom_list.h>
|
|
#include <ipcom_hash.h>
|
|
#include <ipcom_sysvar.h>
|
|
#include <ipcom_time.h>
|
|
|
|
#include "ipdhcpc6.h"
|
|
#include "ipdhcpc6_h.h"
|
|
#include "ipdhcpc6_msg.h"
|
|
#include "ipdhcpc6_if.h"
|
|
#include "ipdhcpc6_info.h"
|
|
#include "ipdhcpc6_ia.h"
|
|
#include "ipdhcpc6_attr.h"
|
|
#include "ipdhcpc6_rtadv.h"
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 4 DEFINES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 5 TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 6 EXTERN PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 7 LOCAL PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 8 DATA
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 9 STATIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_info_clear
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC void
|
|
ipdhcpc6_info_clear(Ipdhcpc6_if_context_t *ifctx)
|
|
{
|
|
ifctx->info.srv = IP_NULL;
|
|
if (ifctx->info.dns)
|
|
{
|
|
/* Remove the DNS, DOMAIN */
|
|
ipcom_sysvar_unset("ipdhcpc.primaryns");
|
|
ipcom_sysvar_unset("ipdhcpc.secondaryns");
|
|
ipcom_sysvar_unset("ipdhcpc.domainname");
|
|
ifctx->info.dns = IP_FALSE;
|
|
}
|
|
|
|
if (ifctx->info.sntp)
|
|
{
|
|
ipcom_sysvar_unset("ipsntp.client.primary.addr");
|
|
ifctx->info.sntp = IP_FALSE;
|
|
}
|
|
|
|
if (ifctx->info.sip)
|
|
{
|
|
ipcom_sysvar_unset("ipsip.server.domain");
|
|
ipcom_sysvar_unset("ipsip.server.address");
|
|
ifctx->info.sip = IP_FALSE;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_info_set
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC void
|
|
ipdhcpc6_info_set(Ipdhcpc6_if_context_t *ifctx,
|
|
Ipdhcpc6_if_server_t *srv)
|
|
{
|
|
/**/
|
|
ifctx->info.srv = srv;
|
|
srv->updated = IP_FALSE;
|
|
|
|
if (srv->ifp->conf.dns == IPDHCPC6_MODE_ENABLED)
|
|
{
|
|
if (srv->attr->dns.num)
|
|
{
|
|
ifctx->info.dns = IP_TRUE;
|
|
ipcom_sysvar_set("ipdnsc.primaryns",
|
|
ipdhcpc6_util_ntoa(&ifctx->context->ntoa,
|
|
srv->attr->dns.array[0]),
|
|
IPCOM_SYSVAR_FLAG_OVERWRITE);
|
|
|
|
if (srv->attr->dns.num > 1)
|
|
{
|
|
ipcom_sysvar_set("ipdnsc.secondaryns",
|
|
ipdhcpc6_util_ntoa(&ifctx->context->ntoa,
|
|
srv->attr->dns.array[1]),
|
|
IPCOM_SYSVAR_FLAG_OVERWRITE);
|
|
}
|
|
|
|
if (srv->attr->dns.num > 2)
|
|
{
|
|
ipcom_sysvar_set("ipdnsc.tertiaryns",
|
|
ipdhcpc6_util_ntoa(&ifctx->context->ntoa,
|
|
srv->attr->dns.array[2]),
|
|
IPCOM_SYSVAR_FLAG_OVERWRITE);
|
|
}
|
|
}
|
|
|
|
if (srv->attr->domain.num)
|
|
{
|
|
ifctx->info.dns = IP_TRUE;
|
|
ipcom_sysvar_set("ipdnsc.domainname",
|
|
srv->attr->domain.array[0],
|
|
IPCOM_SYSVAR_FLAG_OVERWRITE);
|
|
}
|
|
}
|
|
|
|
/**/
|
|
if (srv->ifp->conf.sntp == IPDHCPC6_MODE_ENABLED)
|
|
{
|
|
if (srv->attr->sntp.num)
|
|
{
|
|
ifctx->info.sntp = IP_TRUE;
|
|
ipcom_sysvar_set("ipsntp.client.primary.addr",
|
|
ipdhcpc6_util_ntoa(&ifctx->context->ntoa,
|
|
srv->attr->sntp.array[0]),
|
|
IPCOM_SYSVAR_FLAG_OVERWRITE);
|
|
}
|
|
|
|
}
|
|
if (srv->ifp->conf.sip == IPDHCPC6_MODE_ENABLED)
|
|
{
|
|
if (srv->attr->sip_a.num > 0)
|
|
{
|
|
int i;
|
|
#define IPDHCPC6_SIP_ADDR_BUF_LEN 256
|
|
|
|
char addr_buf[IPDHCPC6_SIP_ADDR_BUF_LEN];
|
|
const char *pstr;
|
|
int pstr_offset = 0;
|
|
|
|
ifctx->info.sip = IP_TRUE;
|
|
/* Loop for each addresses. Covert the addesses to string format */
|
|
for(i = 0;i < srv->attr->sip_a.num; i++)
|
|
{
|
|
pstr = ipdhcpc6_util_ntoa(&ifctx->context->ntoa,
|
|
srv->attr->sip_a.array[i]);
|
|
/* pstr will never be NULL, no need to check */
|
|
if ((pstr_offset + ipcom_strlen(pstr)) > IPDHCPC6_SIP_ADDR_BUF_LEN)
|
|
{
|
|
IPCOM_LOG0(INFO, "ipdhcpc6_info_set: the number of sip server addresses is too large to record.\n");
|
|
break;
|
|
}
|
|
|
|
ipcom_sprintf(addr_buf + pstr_offset,
|
|
"%s;",
|
|
pstr);
|
|
pstr_offset += (ipcom_strlen(pstr) + 1);
|
|
}
|
|
ipcom_sysvar_set("ipsip.server.address",
|
|
addr_buf,
|
|
IPCOM_SYSVAR_FLAG_OVERWRITE);
|
|
|
|
}
|
|
if (srv->attr->sip_d.num > 0)
|
|
{
|
|
int i;
|
|
|
|
#define IPDHCPC6_SIP_DOMAIN_BUF_LEN 256
|
|
|
|
char domain_buf[IPDHCPC6_SIP_DOMAIN_BUF_LEN];
|
|
char *pstr;
|
|
int pstr_offset = 0;
|
|
|
|
ifctx->info.sip = IP_TRUE;
|
|
|
|
/* Loop for each domain names */
|
|
for(i = 0;i < srv->attr->sip_d.num; i++)
|
|
{
|
|
pstr = srv->attr->sip_d.array[i];
|
|
/* pstr will never be NULL, no need to check */
|
|
if ((pstr_offset + ipcom_strlen(pstr)) > IPDHCPC6_SIP_DOMAIN_BUF_LEN)
|
|
{
|
|
IPCOM_LOG0(INFO,"ipdhcpc6_info_set: the number of sip server domain names is too large to record.\n");
|
|
break;
|
|
}
|
|
ipcom_sprintf(domain_buf + pstr_offset,
|
|
"%s;",
|
|
pstr);
|
|
pstr_offset += (ipcom_strlen(pstr) + 1);
|
|
}
|
|
ipcom_sysvar_set("ipsip.server.domain",
|
|
domain_buf,
|
|
IPCOM_SYSVAR_FLAG_OVERWRITE);
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_info_server_select
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC Ipdhcpc6_if_server_t *
|
|
ipdhcpc6_info_server_select(Ipdhcpc6_if_context_t *ifctx)
|
|
{
|
|
Ipdhcpc6_if_t *ifp;
|
|
Ip_u32 best = 0;
|
|
Ipdhcpc6_if_server_t *bestsrv = IP_NULL;
|
|
|
|
|
|
ifp = IPCOM_LIST_FIRST(&ifctx->ifp_head);
|
|
while (ifp != IP_NULL)
|
|
{
|
|
Ipdhcpc6_if_server_t *srv;
|
|
srv = IPCOM_LIST_FIRST(&ifp->servers);
|
|
while (srv != IP_NULL)
|
|
{
|
|
if (ifp->runtime.other == IPDHCPC6_MODE_ENABLED)
|
|
{
|
|
Ip_u32 points = 0;
|
|
if (ifp->conf.dns == IPDHCPC6_MODE_ENABLED)
|
|
{
|
|
if (srv->attr->dns.num)
|
|
points++;
|
|
if (srv->attr->domain.num)
|
|
points++;
|
|
}
|
|
|
|
if (ifp->conf.sntp == IPDHCPC6_MODE_ENABLED)
|
|
{
|
|
if (srv->attr->sntp.num)
|
|
points++;
|
|
|
|
}
|
|
if (ifp->conf.sip == IPDHCPC6_MODE_ENABLED)
|
|
{
|
|
if (srv->attr->sip_a.num)
|
|
points++;
|
|
if (srv->attr->sip_d.num)
|
|
points++;
|
|
}
|
|
|
|
if (points > best)
|
|
{
|
|
best = points;
|
|
bestsrv = srv;
|
|
}
|
|
|
|
}
|
|
srv = IPCOM_LIST_NEXT(&srv->next);
|
|
}
|
|
|
|
ifp = IPCOM_LIST_NEXT(&ifp->next);
|
|
}
|
|
|
|
return bestsrv;
|
|
}
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 10 GLOBAL FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipdhcpc6_info_update
|
|
*===========================================================================
|
|
* Description: Verify the information state.
|
|
* Parameters: ifctx - The interface context.
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_GLOBAL void
|
|
ipdhcpc6_info_update(Ipdhcpc6_if_context_t *ifctx)
|
|
{
|
|
Ipdhcpc6_if_server_t *srv = ipdhcpc6_info_server_select(ifctx);
|
|
|
|
/* Selected new */
|
|
if (srv != ifctx->info.srv ||
|
|
(srv && srv->updated))
|
|
{
|
|
/**/
|
|
ipdhcpc6_info_clear(ifctx);
|
|
if (srv)
|
|
ipdhcpc6_info_set(ifctx, srv);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 11 PUBLIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|