0
mirror of https://github.com/Indemsys/Frequency_Inverter.git synced 2026-05-09 14:12:58 +00:00
Files
2022-01-04 12:22:53 +02:00

531 lines
12 KiB
C

/**HEADER*******************************************************************************
*
* Copyright (c) 2011 , Freescale Semiconductor;
* All Rights Reserved
*
****************************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************************/
/*
* Portions Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <string.h>
#include <ctype.h>
#include <rtcs.h>
#include <addrinfo.h>
#define SUCCESS 0
/*% afd structure definition */
static struct afd {
int a_af;
unsigned int a_addrlen;
unsigned int a_socklen;
} afdl [] = {
/*!
* First entry is linked last...
*/
{ AF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in) },
{ AF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6) },
{0, 0, 0},
};
#define ENI_NOSERVNAME 1
#define ENI_NOHOSTNAME 2
#define ENI_MEMORY 3
#define ENI_SYSTEM 4
#define ENI_FAMILY 5
#define ENI_SALEN 6
#define ENI_NOSOCKET 7
/*!
* The test against 0 is there to keep the Solaris compiler
* from complaining about "end-of-loop code not reached".
*/
#define ERR(code) \
do { result = (code); \
if (result != 0) goto cleanup; \
} while (0)
/*FUNCTION*-------------------------------------------------------------
*
* Function Name : getnameinfo()
* Returned Value : RTCS_OK or error code
* Comments :
* Lightweight resolver socket address structure to hostname and service name.
*
*END*-----------------------------------------------------------------*/
int_32 getnameinfo
(
const struct sockaddr *sa,
unsigned int salen,
char *host,
unsigned int hostlen,
char *serv,
unsigned int servlen,
int flags
)
{
struct afd *afd;
struct servent *sp = NULL;
unsigned short port;
#ifdef LWRES_PLATFORM_HAVESALEN
unsigned int len;
#endif
int family, i;
const void *addr;
char *p;
#if 0
unsigned long v4a;
unsigned char pfx;
#endif
#if 0
char numserv[sizeof("65000")];
#endif
char numaddr[sizeof("abcd:abcd:abcd:abcd:abcd:abcd:255.255.255.255")
+ 1 + sizeof("4294967295")];
const char *proto;
uint_32 lwf = 0;
lwres_context_t *lwrctx = NULL;
lwres_gnbaresponse_t *by = NULL;
int result = SUCCESS;
int n;
if (sa == NULL)
ERR(ENI_NOSOCKET);
#ifdef LWRES_PLATFORM_HAVESALEN
len = sa->sa_len;
if (len != salen)
ERR(ENI_SALEN);
#endif
/*family = sa->sa_family;*/
family = sa->sa_family;
for (i = 0; afdl[i].a_af; i++)
if (afdl[i].a_af == family) {
afd = &afdl[i];
goto found;
}
ERR(ENI_FAMILY);
found:
if (salen != afd->a_socklen)
ERR(ENI_SALEN);
switch (family) {
case AF_INET:
port = ((const struct sockaddr_in *)sa)->sin_port;
addr = &((const struct sockaddr_in *)sa)->sin_addr.s_addr;
break;
case AF_INET6:
port = ((const struct sockaddr_in6 *)sa)->sin6_port;
addr = ((const struct sockaddr_in6 *)sa)->sin6_addr.s6_addr;
break;
default:
port = 0;
addr = NULL;
// INSIST(0);//#define INSIST(x) assert(x)
}
proto = (flags & NI_DGRAM) ? "udp" : "tcp";
if (serv == NULL || servlen == 0U) {
/*
* Caller does not want service.
*/
#if 0 /*We do not support getservbyport function */
}
else if ((flags & NI_NUMERICSERV) != 0 ||(sp = getservbyport(port, proto)) == NULL)
{
snprintf(numserv, sizeof(numserv), "%d", ntohs(port));
if ((strlen(numserv) + 1) > servlen)
{
ERR(ENI_MEMORY);
}
strcpy(serv, numserv);
}
#endif
}else {
if ((strlen(sp->s_name) + 1) > servlen)
{
ERR(ENI_MEMORY);
}
strcpy(serv, sp->s_name);
}
if (host == NULL || hostlen == 0U) {
/*
* What should we do?
*/
} else if (flags & NI_NUMERICHOST) {
if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) == NULL)
{
ERR(ENI_SYSTEM);
}
if (afd->a_af == AF_INET6 && ((const struct sockaddr_in6 *)sa)->sin6_scope_id)
{
char *p = numaddr + strlen(numaddr);
const char *stringscope = NULL;
#if 0
if ((flags & NI_NUMERICSCOPE) == 0) {
/*
* Vendors may want to add support for
* non-numeric scope identifier.
*/
stringscope = foo;
}
#endif
if (stringscope == NULL)
{
//snprintf(p, sizeof(numaddr) - (p - numaddr),"%%%u",((const struct sockaddr_in6 *)sa)->sin6_scope_id);
sprintf(p,"%%%u",((const struct sockaddr_in6 *)sa)->sin6_scope_id);
} else {
//snprintf(p, sizeof(numaddr) - (p - numaddr),"%%%s", stringscope);
sprintf(p,"%%%s", stringscope);
}
}
//#endif
if (strlen(numaddr) + 1 > hostlen)
ERR(ENI_MEMORY);
strcpy(host, numaddr);
} else {
switch (family) {
case AF_INET:
lwf = LWRES_ADDRTYPE_V4;
break;
case AF_INET6:
lwf = LWRES_ADDRTYPE_V6;
break;
default:
return (ENI_FAMILY);
}
n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
if (n == 0)
{
//(void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
}
if (n == 0)
{
//n = lwres_getnamebyaddr(lwrctx, lwf, (lwres_uint16_t)afd->a_addrlen,addr, &by);
}
if (n == 0)
{
if (flags & NI_NOFQDN)
{
p = strchr(by->realname, '.');
if (p)
{
*p = '\0';
}
}
if ((strlen(by->realname) + 1) > hostlen)
{
ERR(ENI_MEMORY);
}
strcpy(host, by->realname);
} else {
if (flags & NI_NAMEREQD)
{
ERR(ENI_NOHOSTNAME);
}
if (inet_ntop(afd->a_af, addr, numaddr,sizeof(numaddr))== NULL)
{
ERR(ENI_NOHOSTNAME);
}
if ((strlen(numaddr) + 1) > hostlen)
{
ERR(ENI_MEMORY);
}
strcpy(host, numaddr);
}
}
result = SUCCESS;
cleanup:
if (by != NULL)
lwres_gnbaresponse_free(lwrctx, &by);
if (lwrctx != NULL) {
lwres_conf_clear(lwrctx);
lwres_context_destroy(&lwrctx);
}
return (result);
}
/*%
* Creates a #lwres_context_t structure for use in
* lightweight resolver operations.
*/
uint_32 lwres_context_create
(
lwres_context_t **contextp,
void *arg,
lwres_malloc_t malloc_function,
lwres_free_t free_function,
unsigned int flags
)
{
lwres_context_t *ctx;
//REQUIRE(contextp != NULL && *contextp == NULL);
/*
* If we were not given anything special to use, use our own
* functions. These are just wrappers around malloc() and free().
*/
if (malloc_function == NULL || free_function == NULL) {
// REQUIRE(malloc_function == NULL);
// REQUIRE(free_function == NULL);
malloc_function = lwres_malloc;
free_function = lwres_free;
}
ctx = malloc_function(arg, sizeof(lwres_context_t));
if (ctx == NULL)
return (LWRES_R_NOMEMORY);
/*
* Set up the context.
*/
ctx->malloc = malloc_function;
ctx->free = free_function;
ctx->arg = arg;
ctx->sock = -1;
ctx->r_timeout = LWRES_DEFAULT_TIMEOUT;
//b23362
//ctx->serial = time(NULL); /* XXXMLG or BEW */
ctx->use_ipv4 = 1;
ctx->use_ipv6 = 1;
if ((flags & (LWRES_CONTEXT_USEIPV4 | LWRES_CONTEXT_USEIPV6)) ==
LWRES_CONTEXT_USEIPV6) {
ctx->use_ipv4 = 0;
}
if ((flags & (LWRES_CONTEXT_USEIPV4 | LWRES_CONTEXT_USEIPV6)) ==
LWRES_CONTEXT_USEIPV4) {
ctx->use_ipv6 = 0;
}
/*
* Init resolv.conf bits.
*/
lwres_conf_init(ctx);
*contextp = ctx;
return (LWRES_R_SUCCESS);
}
/*% Release the memory in resolver context ctx that was allocated to the lwres_gnbaresponse_t. */
void lwres_gnbaresponse_free
(
lwres_context_t *ctx,
lwres_gnbaresponse_t **structp
)
{
lwres_gnbaresponse_t *gnba;
//REQUIRE(ctx != NULL);
//REQUIRE(structp != NULL && *structp != NULL);
gnba = *structp;
*structp = NULL;
if (gnba->naliases > 0) {
CTXFREE(gnba->aliases, sizeof(char *) * gnba->naliases);
CTXFREE(gnba->aliaslen,
sizeof(uint_16) * gnba->naliases);
}
if (gnba->base != NULL)
CTXFREE(gnba->base, gnba->baselen);
CTXFREE(gnba, sizeof(lwres_gnbaresponse_t));
}
/*% Frees up all the internal memory used by the config data structure, returning it to the lwres_context_t. */
void lwres_conf_clear
(
lwres_context_t *ctx
)
{
int i;
lwres_conf_t *confdata;
//REQUIRE(ctx != NULL);
confdata = &ctx->confdata;
for (i = 0; i < confdata->nsnext; i++)
lwres_resetaddr(&confdata->nameservers[i]);
if (confdata->domainname != NULL) {
CTXFREE(confdata->domainname,
strlen(confdata->domainname) + 1);
confdata->domainname = NULL;
}
for (i = 0; i < confdata->searchnxt; i++) {
if (confdata->search[i] != NULL) {
CTXFREE(confdata->search[i],
strlen(confdata->search[i]) + 1);
confdata->search[i] = NULL;
}
}
for (i = 0; i < LWRES_CONFMAXSORTLIST; i++) {
lwres_resetaddr(&confdata->sortlist[i].addr);
lwres_resetaddr(&confdata->sortlist[i].mask);
}
confdata->nsnext = 0;
confdata->lwnext = 0;
confdata->domainname = NULL;
confdata->searchnxt = 0;
confdata->sortlistnxt = 0;
confdata->resdebug = 0;
confdata->ndots = 1;
confdata->no_tld_query = 0;
}
/*%
Destroys a #lwres_context_t, closing its socket.
contextp is a pointer to a pointer to the context that is
to be destroyed. The pointer will be set to NULL
when the context has been destroyed.
*/
void lwres_context_destroy
(
lwres_context_t **contextp
)
{
lwres_context_t *ctx;
// REQUIRE(contextp != NULL && *contextp != NULL);
ctx = *contextp;
*contextp = NULL;
//b23362
// if (ctx->sock != -1) {
//
// (void)close(ctx->sock);
// ctx->sock = -1;
// }
CTXFREE(ctx, sizeof(lwres_context_t));
}
void *lwres_malloc
(
void *arg,
unsigned int len
)
{
void *mem;
//UNUSED(arg);
mem = RTCS_mem_alloc_system((_mem_size) len);
//mem = malloc(len);
if (mem == NULL)
return (NULL);
memset(mem, 0xe5, len);
return (mem);
}
void lwres_free
(
void *arg,
void *mem,
unsigned int len
)
{
// UNUSED(arg);
memset(mem, 0xa9, len);
_mem_free(mem);
}
/*% intializes data structure for subsequent config parsing. */
void lwres_conf_init
(
lwres_context_t *ctx
)
{
int i;
lwres_conf_t *confdata;
// REQUIRE(ctx != NULL);
confdata = &ctx->confdata;
confdata->nsnext = 0;
confdata->lwnext = 0;
confdata->domainname = NULL;
confdata->searchnxt = 0;
confdata->sortlistnxt = 0;
confdata->resdebug = 0;
confdata->ndots = 1;
confdata->no_tld_query = 0;
for (i = 0; i < LWRES_CONFMAXNAMESERVERS; i++)
lwres_resetaddr(&confdata->nameservers[i]);
for (i = 0; i < LWRES_CONFMAXSEARCH; i++)
confdata->search[i] = NULL;
for (i = 0; i < LWRES_CONFMAXSORTLIST; i++) {
lwres_resetaddr(&confdata->sortlist[i].addr);
lwres_resetaddr(&confdata->sortlist[i].mask);
}
}
void lwres_resetaddr
(
lwres_addr_t *addr
)
{
// REQUIRE(addr != NULL);
memset(addr->address, 0, LWRES_ADDR_MAXLEN);
addr->family = 0;
addr->length = 0;
}