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

694 lines
19 KiB
C

/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmip_attr.c,v $ $Revision: 1.6 $
* $Source: /home/interpeak/CVSRoot/ipmip/src/ipmip_attr.c,v $
* $Author: jhorteli $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelis@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#include "ipmip_config.h"
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_clib.h>
#include <ipcom_clib2.h>
#include <ipcom_err.h>
#include <ipcom_inet.h>
#include <ipcom_ipd.h>
#include <ipcom_list.h>
#include <ipcom_hash.h>
#include <ipcom_os.h>
#include <ipcom_sock.h>
#include <ipcom_sock.h>
#include <ipcom_sock2.h>
#include <ipcom_sysctl.h>
#include <ipcom_syslog.h>
#include <ipcom_sysvar.h>
#include <ipmip.h>
#include <private/ipmip_util.h>
#include <private/ipmip_buffer.h>
#include <private/ipmip_context.h>
#include <private/ipmip_attr.h>
#include <private/ipmip_cli.h>
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
#define IPCOM_SYSLOG_PRIORITY IPCOM_LOG_DEBUG2
#define IPCOM_SYSLOG_FACILITY IPCOM_LOG_IPMIP
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
IP_STATIC Ip_size_t
ipmip_attr_hdr_create(Ipmip_buffer_t *buf,
Ip_u32 subsystem,
Ip_u32 errcode,
Ip_u32 seq,
Ip_u16 type,
Ip_u16 flags)
{
struct Ipmip_attr_header *hdr;
Ip_u32 size = IPMIP_ATTR_HDR_LENGTH(0);
Ip_size_t off = IPMIP_BUFFER_SIZE(buf);
if (!ipmip_buffer_reserve(buf, size))
return 0;
/* Initialize the netlink header */
hdr = (struct Ipmip_attr_header *)IPMIP_BUFFER_CURRENT(buf);
IP_SET_HTONS(&hdr->ah_type, type);
IP_SET_HTONS(&hdr->ah_flags, flags);
IP_SET_HTONL(&hdr->ah_len, size);
IP_SET_HTONL(&hdr->ah_subsystem, subsystem);
IP_SET_32ON8(&hdr->ah_sequence, seq);
IP_SET_HTONL(&hdr->ah_errcode, errcode);
/* Move past */
ipmip_buffer_append(buf, IP_NULL, size);
return off;
}
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
IP_GLOBAL int
ipmip_attr_command(struct Ipmip_context *ctx,
struct Ipmip_proc *proc,
struct Ipmip_cli_message *request)
{
struct Ipmip_attr_header *hdr = (struct Ipmip_attr_header *)IPMIP_BUFFER_DATA(&request->request);
Ip_size_t rhdr = 0;
struct Ipmip_attr *rta;
switch (IPMIP_ATTR_HDR_TYPE(hdr))
{
case IPMIP_CLI_EVENT_GET:
rhdr = ipmip_log_attr_request_events(ctx, proc, request);
break;
case IPMIP_CLI_EVENT_FLUSH:
rhdr = ipmip_attr_hdr_ack(&request->message, hdr);
ipmip_log_event_flush(ctx, proc);
break;
case IPMIP_CLI_EVENT_HISTORY_SET:
rta = ipmip_attr_hdr_find(hdr, IPMIP_CLI_ITEM_SIZE);
if (rta == IP_NULL)
return -IP_ERRNO_EINVAL;
rhdr = ipmip_attr_hdr_ack(&request->message, hdr);
ipmip_log_event_backlog(ctx, proc, ipmip_attr_get_u32(rta));
break;
case IPMIP_CLI_EVENT_HISTORY_GET:
ipmip_log_attr_request_history(ctx, proc, request);
break;
case IPMIP_CLI_LOG_LEVEL_SET:
rta = ipmip_attr_hdr_find(hdr, IPMIP_CLI_ITEM_SIZE);
if (rta == IP_NULL)
return -IP_ERRNO_EINVAL;
rhdr = ipmip_attr_hdr_ack(&request->message, hdr);
ipmip_log_loglevel(ctx, proc, ipmip_attr_get_u32(rta));
break;
case IPMIP_CLI_LOG_LEVEL_GET:
ipmip_log_attr_request_loglevel(ctx, proc, request);
break;
case IPMIP_CLI_CONFIG_GET:
default:
return -IP_ERRNO_ENOPROTOOPT;
}
/* If we have a reply header; terminate it */
ipmip_attr_hdr_finalize(&request->message, rhdr);
/* Commit the reply */
ipmip_cli_message_commit(ctx, proc, request);
return 0;
}
IP_GLOBAL Ip_size_t
ipmip_attr_put(Ipmip_buffer_t *buf,
Ip_u16 attrtype,
Ip_u32 attrlen,
const void *data)
{
Ip_u16 len = IPMIP_ATTR_LENGTH(attrlen);
Ip_size_t off = ipmip_buffer_append(buf, IP_NULL, len);
struct Ipmip_attr *attr = ipmip_buffer_offset(buf, off);
IP_SET_HTONS(&attr->attr_type, attrtype);
IP_SET_HTONS(&attr->attr_len, len);
if (data)
ipcom_memcpy(IPMIP_ATTR_DATA(attr), data, attrlen);
return off;
}
IP_GLOBAL Ip_size_t
ipmip_attr_put_u32(Ipmip_buffer_t *buf,
Ip_u16 attrtype,
Ip_u32 attrval)
{
attrval = ip_htonl(attrval);
/* Do invoke the real put function */
return ipmip_attr_put(buf, attrtype, sizeof(attrval), &attrval);
}
#ifdef IPCOM_USE_INET
IP_GLOBAL Ip_size_t
ipmip_attr_put_inet(Ipmip_buffer_t *buf,
Ip_u16 attrtype,
Ip_u32 attrval)
{
/* Do invoke the real put function */
return ipmip_attr_put(buf, attrtype, sizeof(attrval), &attrval);
}
#endif
#ifdef IPCOM_USE_INET6
IP_GLOBAL Ip_size_t
ipmip_attr_put_inet6(Ipmip_buffer_t *buf,
Ip_u16 attrtype,
const struct Ip_in6_addr *attrval)
{
/* Do invoke the real put function */
return ipmip_attr_put(buf, attrtype, sizeof(*attrval), attrval);
}
#endif
IP_GLOBAL Ip_size_t
ipmip_attr_put_u64(Ipmip_buffer_t *buf,
Ip_u16 attrtype,
Ip_u64 attrval)
{
attrval = IPMIP_BSWAP64(attrval);
/* Do invoke the real put function */
return ipmip_attr_put(buf, attrtype, sizeof(attrval), &attrval);
}
IP_GLOBAL Ip_size_t
ipmip_attr_put_time_t(Ipmip_buffer_t *buf,
Ip_u16 attrtype,
Ip_time_t attrval)
{
/* Do invoke the real put function */
return ipmip_attr_put_u64(buf, attrtype, (Ip_u64)attrval);
}
IP_GLOBAL Ip_size_t
ipmip_attr_put_strn(Ipmip_buffer_t *buf,
Ip_u16 attrtype,
const char *str,
Ip_size_t size)
{
Ip_size_t off = ipmip_attr_put(buf, attrtype, size + 1, IP_NULL);
struct Ipmip_attr *attr = ipmip_buffer_offset(buf, off);
ipcom_memcpy(IPMIP_ATTR_DATA(attr), str, size);
*(((char *)IPMIP_ATTR_DATA(attr)) + size) = '\0';
return off;
}
IP_GLOBAL Ip_size_t
ipmip_attr_put_str(Ipmip_buffer_t *buf,
Ip_u16 attrtype,
const char *str)
{
/* Add it */
return ipmip_attr_put(buf, attrtype, ipcom_strlen(str) + 1, str);
}
IP_GLOBAL Ip_size_t
ipmip_attr_begin(Ipmip_buffer_t *buf,
Ip_u16 attrtype)
{
/**/
return ipmip_attr_put(buf, attrtype, 0, IP_NULL);
}
IP_GLOBAL void
ipmip_attr_end(Ipmip_buffer_t *buf,
Ip_size_t off)
{
Ip_size_t len = IPMIP_BUFFER_SIZE(buf) - off;
struct Ipmip_attr *attr = ipmip_buffer_offset(buf, off);
IP_SET_HTONS(&attr->attr_len, len);
}
IP_GLOBAL void
ipmip_attr_parse(int maxattr,
struct Ipmip_attr *attr,
Ip_size_t attrlen,
struct Ipmip_attr **attrtable)
{
ipcom_memset(attrtable, 0, sizeof(struct Ipmip_attr *) * maxattr);
while (IPMIP_ATTR_OK(attr, attrlen))
{
Ip_u16 flavor = IPMIP_ATTR_TYPE(attr);
if (flavor)
{
if (flavor < maxattr)
attrtable[flavor] = attr;
}
attr = IPMIP_ATTR_NEXT(attr, attrlen);
}
}
IP_GLOBAL void
ipmip_attr_hdr_parse(int maxattr,
struct Ipmip_attr_header *attrhdr,
struct Ipmip_attr **attrtable)
{
ipmip_attr_parse(maxattr, IPMIP_ATTR_HDR_DATA(attrhdr), IPMIP_ATTR_HDR_PAYLOAD(attrhdr), attrtable);
}
IP_GLOBAL struct Ipmip_attr *
ipmip_attr_find(struct Ipmip_attr *attr,
Ip_size_t attrlen,
Ip_u16 attrtype)
{
while (IPMIP_ATTR_OK(attr, (int)attrlen))
{
if (IPMIP_ATTR_TYPE(attr) == attrtype)
return attr;
attr = IPMIP_ATTR_NEXT(attr, attrlen);
}
return IP_NULL;
}
IP_GLOBAL struct Ipmip_attr *
ipmip_attr_payload_find(struct Ipmip_attr *attr,
Ip_u16 attrtype)
{
/**/
return ipmip_attr_find(IPMIP_ATTR_DATA(attr), IPMIP_ATTR_PAYLOAD(attr), attrtype);
}
IP_GLOBAL Ip_u32
ipmip_attr_payload_find_u32(struct Ipmip_attr *attr,
Ip_u16 attrtype)
{
/**/
return ipmip_attr_get_u32(ipmip_attr_payload_find(attr, attrtype));
}
IP_GLOBAL Ip_time_t
ipmip_attr_payload_find_time_t(struct Ipmip_attr *attr,
Ip_u16 attrtype)
{
/**/
return ipmip_attr_get_time_t(ipmip_attr_payload_find(attr, attrtype));
}
IP_GLOBAL Ip_u64
ipmip_attr_payload_find_u64(struct Ipmip_attr *attr,
Ip_u16 attrtype)
{
/**/
return ipmip_attr_get_u64(ipmip_attr_payload_find(attr, attrtype));
}
#ifdef IPCOM_USE_INET
IP_GLOBAL Ip_u32
ipmip_attr_payload_find_inet(struct Ipmip_attr *attr,
Ip_u16 attrtype)
{
/**/
return ipmip_attr_get_inet(ipmip_attr_payload_find(attr, attrtype));
}
#endif
#ifdef IPCOM_USE_INET6
IP_GLOBAL struct Ip_in6_addr *
ipmip_attr_payload_find_inet6(struct Ipmip_attr *attr,
Ip_u16 attrtype)
{
/**/
return ipmip_attr_get_inet6(ipmip_attr_payload_find(attr, attrtype));
}
#endif
IP_GLOBAL char *
ipmip_attr_payload_find_str(struct Ipmip_attr *attr,
Ip_u16 attrtype)
{
/**/
return ipmip_attr_get_str(ipmip_attr_payload_find(attr, attrtype));
}
IP_GLOBAL void *
ipmip_attr_payload_find_data(struct Ipmip_attr *attr,
Ip_u16 attrtype)
{
/**/
return ipmip_attr_get_data(ipmip_attr_payload_find(attr, attrtype));
}
IP_GLOBAL struct Ipmip_attr *
ipmip_attr_hdr_find(struct Ipmip_attr_header *attrhdr,
Ip_u16 attrtype)
{
/**/
return ipmip_attr_find(IPMIP_ATTR_HDR_DATA(attrhdr), IPMIP_ATTR_HDR_PAYLOAD(attrhdr), attrtype);
}
IP_GLOBAL Ip_u32
ipmip_attr_hdr_find_u32(struct Ipmip_attr_header *attrhdr,
Ip_u16 attrtype)
{
/**/
return ipmip_attr_get_u32(ipmip_attr_hdr_find(attrhdr, attrtype));
}
IP_GLOBAL Ip_u64
ipmip_attr_hdr_find_u64(struct Ipmip_attr_header *attrhdr,
Ip_u16 attrtype)
{
/**/
return ipmip_attr_get_u64(ipmip_attr_hdr_find(attrhdr, attrtype));
}
IP_GLOBAL char *
ipmip_attr_hdr_find_str(struct Ipmip_attr_header *attrhdr,
Ip_u16 attrtype)
{
/**/
return ipmip_attr_get_str(ipmip_attr_hdr_find(attrhdr, attrtype));
}
IP_GLOBAL void *
ipmip_attr_hdr_find_data(struct Ipmip_attr_header *attrhdr,
Ip_u16 attrtype)
{
/**/
return ipmip_attr_get_data(ipmip_attr_hdr_find(attrhdr, attrtype));
}
#ifdef IPCOM_USE_INET
IP_GLOBAL Ip_u32
ipmip_attr_hdr_find_inet(struct Ipmip_attr_header *attrhdr,
Ip_u16 attrtype)
{
/**/
return ipmip_attr_get_inet(ipmip_attr_hdr_find(attrhdr, attrtype));
}
#endif
#ifdef IPCOM_USE_INET6
IP_GLOBAL struct Ip_in6_addr *
ipmip_attr_hdr_find_inet6(struct Ipmip_attr_header *attrhdr,
Ip_u16 attrtype)
{
/**/
return ipmip_attr_get_inet6(ipmip_attr_hdr_find(attrhdr, attrtype));
}
#endif
IP_GLOBAL Ip_u32
ipmip_attr_get_u32(struct Ipmip_attr *attr)
{
if (attr)
return IP_GET_NTOHL(IPMIP_ATTR_DATA(attr));
return 0;
}
IP_GLOBAL Ip_u64
ipmip_attr_get_u64(struct Ipmip_attr *attr)
{
if (attr)
return ipmip_util_bswap64(IPMIP_ATTR_DATA(attr));
return 0;
}
IP_GLOBAL Ip_time_t
ipmip_attr_get_time_t(struct Ipmip_attr *attr)
{
if (attr)
return (Ip_time_t)ipmip_attr_get_u64(attr);
return 0;
}
#ifdef IPCOM_USE_INET
IP_GLOBAL Ip_u32
ipmip_attr_get_inet(struct Ipmip_attr *attr)
{
if (attr)
return IP_GET_32ON8(IPMIP_ATTR_DATA(attr));
return 0;
}
#endif
#ifdef IPCOM_USE_INET6
IP_GLOBAL struct Ip_in6_addr *
ipmip_attr_get_inet6(struct Ipmip_attr *attr)
{
if (attr)
return (struct Ip_in6_addr *)IPMIP_ATTR_DATA(attr);
return IP_NULL;
}
#endif
IP_GLOBAL char *
ipmip_attr_get_str(struct Ipmip_attr *attr)
{
if (attr)
return (char *)IPMIP_ATTR_DATA(attr);
return IP_NULL;
}
IP_GLOBAL Ip_size_t
ipmip_attr_get_strlen0(struct Ipmip_attr *attr)
{
if (attr)
return ipmip_util_strstrip0(IPMIP_ATTR_DATA(attr), IPMIP_ATTR_PAYLOAD(attr));
return 0;
}
IP_GLOBAL void *
ipmip_attr_get_data(struct Ipmip_attr *attr)
{
if (attr)
return (void *)IPMIP_ATTR_DATA(attr);
return IP_NULL;
}
IP_GLOBAL Ip_size_t
ipmip_attr_hdr_req_create(Ipmip_buffer_t *buf,
Ip_u32 subsystem,
Ip_u32 seq,
Ip_u16 type)
{
return ipmip_attr_hdr_create(buf, subsystem, 0, seq, type, 0);
}
IP_GLOBAL Ip_size_t
ipmip_attr_hdr_ack_create(Ipmip_buffer_t *buf,
Ip_u32 subsystem,
Ip_u32 seq,
Ip_u16 type)
{
return ipmip_attr_hdr_create(buf, subsystem, 0, seq, type, IPMIP_ATTR_HEADER_ACK);
}
IP_GLOBAL Ip_size_t
ipmip_attr_hdr_ack(Ipmip_buffer_t *buf,
struct Ipmip_attr_header *hdr)
{
return ipmip_attr_hdr_ack_create(buf, IPMIP_ATTR_HDR_SYSTEM(hdr), IPMIP_ATTR_HDR_SEQUENCE(hdr), IPMIP_ATTR_HDR_TYPE(hdr));
}
IP_GLOBAL Ip_size_t
ipmip_attr_hdr_err_create(Ipmip_buffer_t *buf,
Ip_u32 subsystem,
Ip_u32 seq,
Ip_u16 type,
Ip_u32 errcode,
const char *errmsg)
{
Ip_size_t off = ipmip_attr_hdr_create(buf, subsystem, errcode, seq, type, IPMIP_ATTR_HEADER_ACK);
if (errmsg)
ipmip_attr_put_str(buf, IPMIP_ATTR_MESSAGE, errmsg);
return off;
}
IP_GLOBAL Ip_size_t
ipmip_attr_hdr_err(Ipmip_buffer_t *buf,
struct Ipmip_attr_header *hdr,
Ip_u32 errcode,
const char *errmsg)
{
return ipmip_attr_hdr_err_create(buf, IPMIP_ATTR_HDR_SYSTEM(hdr),IPMIP_ATTR_HDR_SEQUENCE(hdr), IPMIP_ATTR_HDR_TYPE(hdr), errcode, errmsg);
}
IP_GLOBAL void
ipmip_attr_hdr_finalize(Ipmip_buffer_t *buf,
Ip_size_t off)
{
struct Ipmip_attr_header *hdr = (struct Ipmip_attr_header *)ipmip_buffer_offset(buf,off);
Ip_u32 size = IPMIP_BUFFER_SIZE(buf) - off;
IP_SET_HTONL(&hdr->ah_len, size);
}
/*
*===========================================================================
* ipmip_cli_daemon_iter_init_request
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_GLOBAL Ipmip_attr_iter_t *
ipmip_attr_hdr_iter_init(struct Ipmip_attr_header *hdr,
Ipmip_attr_iter_t *iter)
{
iter->rta = IPMIP_ATTR_HDR_DATA(hdr);
iter->rta_size = IPMIP_ATTR_HDR_PAYLOAD(hdr);
/**/
return iter;
}
/*
*===========================================================================
* ipmip_cli_daemon_iter_rta_init
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_GLOBAL Ipmip_attr_iter_t *
ipmip_attr_payload_iter_init(struct Ipmip_attr *attr,
Ipmip_attr_iter_t *iter)
{
iter->rta = IPMIP_ATTR_DATA(attr);
iter->rta_size = IPMIP_ATTR_PAYLOAD(attr);
/**/
return iter;
}
/*
*===========================================================================
* ipmip_cli_daemon_iter_next
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_GLOBAL struct Ipmip_attr *
ipmip_attr_iter_next(Ipmip_attr_iter_t *iter,
Ip_u16 type)
{
while (IPMIP_ATTR_OK(iter->rta, iter->rta_size))
{
if (IPMIP_ATTR_TYPE(iter->rta) == type)
{
struct Ipmip_attr *rta = iter->rta;
iter->rta = IPMIP_ATTR_NEXT(iter->rta, iter->rta_size);
return rta;
}
iter->rta = IPMIP_ATTR_NEXT(iter->rta, iter->rta_size);
}
/**/
return IP_NULL;
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/