/* ****************************************************************************** * 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 ****************************************************************************** */ /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ #include "ipmip_config.h" /* **************************************************************************** * 3 INCLUDE FILES **************************************************************************** */ #define IPCOM_USE_CLIB_PROTO #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* **************************************************************************** * 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 **************************************************************************** */