From 5aca0dd1661bc87a7927c00cf95e0c8aa6f2e2a0 Mon Sep 17 00:00:00 2001 From: Pablo Bovina Date: Thu, 4 Feb 2021 19:39:15 -0300 Subject: [PATCH] Adding support IPv6 to the fm-trap-subagent Now the server that runs in the fm-trap-subagent is able to recieve messages when it runs in a StarlingX with IPv6 environment. This server is responsible to receive the alarm metada and generate the traps accordingly to the configuration in the master agent. Story: 2008132 Task: 41774 Signed-off-by: Pablo Bovina Change-Id: I89b1d8e7c97d315637b12bcfea0269f2fcf8d452 --- .../docker/stx-fm-trap-subagent/Makefile | 3 +- .../src/wrsAlarmMIBServer.c | 444 ++++++++++++++++++ .../src/wrsAlarmMIBServer.h | 39 ++ .../src/wrsAlarmMIBSubagent.c | 197 ++------ .../src/wrsAlarmMIBTrap.c | 59 ++- .../src/wrsAlarmMIBTrap.h | 3 +- 6 files changed, 588 insertions(+), 157 deletions(-) create mode 100644 stx-snmp-helm/centos/docker/stx-fm-trap-subagent/src/wrsAlarmMIBServer.c create mode 100644 stx-snmp-helm/centos/docker/stx-fm-trap-subagent/src/wrsAlarmMIBServer.h diff --git a/stx-snmp-helm/centos/docker/stx-fm-trap-subagent/Makefile b/stx-snmp-helm/centos/docker/stx-fm-trap-subagent/Makefile index 694cb55..b29eb2f 100644 --- a/stx-snmp-helm/centos/docker/stx-fm-trap-subagent/Makefile +++ b/stx-snmp-helm/centos/docker/stx-fm-trap-subagent/Makefile @@ -16,7 +16,8 @@ STRICT_FLAGS = -Wall -Wstrict-prototypes CFLAGS=-I. $(NETSNMPCFLAGS) $(STRICT_FLAGS) -fPIC SRCS = $(SOURCE)/$(PREFIX)Trap.c \ - $(SOURCE)/$(PREFIX)Subagent.c + $(SOURCE)/$(PREFIX)Subagent.c \ + $(SOURCE)/$(PREFIX)Server.c OBJS = $(SRCS:.c=.o) diff --git a/stx-snmp-helm/centos/docker/stx-fm-trap-subagent/src/wrsAlarmMIBServer.c b/stx-snmp-helm/centos/docker/stx-fm-trap-subagent/src/wrsAlarmMIBServer.c new file mode 100644 index 0000000..6303d29 --- /dev/null +++ b/stx-snmp-helm/centos/docker/stx-fm-trap-subagent/src/wrsAlarmMIBServer.c @@ -0,0 +1,444 @@ +/* +* Copyright (c) 2021 Wind River Systems, Inc. +* +* SPDX-License-Identifier: Apache-2.0 +* +*/ + +#include +#include +#include +#include +#include +#include +#include +#include "wrsAlarmMIBServer.h" +#include "wrsAlarmMIBTrap.h" + +#define HOST_NAME "localhost" +#define MSG_SIZE 4 +#define BACKLOG 1 +#define ENABLE 1 +#define RETRIES 5 +#define RETRIES_MESSAGE_SIZE 20 +#define DEFAULT_ERROR -1 +#define DEFAULT_SUCCESS 0 + +struct sServerInfo { + char address[INET6_ADDRSTRLEN]; + int address_family; + int port; + int fd; + int retries; + int error; +}; + +/* +Returns a ServerInfo error attribute. +*/ +int get_error(ServerInfo server_info){ + assert(server_info != NULL); + return server_info->error; +} + +/* +This procedure attempts to start to listen a Server. +In case of success returns DEFAULT_SUCCESS. +*/ +int init_server(ServerInfo server_info){ + assert(server_info != NULL); + int optval = ENABLE; + int error = DEFAULT_ERROR; + int fd = DEFAULT_ERROR; + + snmp_log(LOG_INFO, "server init_server init on address: %s family: %d port:" + " %d\n", server_info->address, server_info->address_family, + server_info->port); + + fd = socket(server_info->address_family, SOCK_STREAM, 0); + if( fd == DEFAULT_ERROR){ + snmp_log(LOG_ERR, "server init_server socket errno: (%d) (%s)\n", errno, + strerror(errno)); + return DEFAULT_ERROR; + } + server_info->fd = fd; + + error = setsockopt(server_info->fd, SOL_SOCKET, SO_REUSEADDR, + &optval, sizeof optval); + if( error != DEFAULT_SUCCESS){ + snmp_log(LOG_ERR, "server init_server setsockopt errno: (%d) (%s)\n", + errno, strerror(errno)); + close(server_info->fd); + snmp_log(LOG_ERR, "server init_server setsockopt errno: (%d) (%s)\n", + errno, strerror(errno)); + return DEFAULT_ERROR; + } + + switch (server_info -> address_family) { + //When address is IPv4 + case AF_INET: + { + struct sockaddr_in addr_4; + addr_4.sin_family = AF_INET; + addr_4.sin_port = htons(server_info -> port); + error = inet_pton(AF_INET, server_info->address, + &(addr_4.sin_addr.s_addr)); + if(error <= DEFAULT_SUCCESS){ + snmp_log(LOG_ERR, + "server init_server inet_pton error ip address %s with " + "error: %d errno: (%d) (%s)\n", + server_info->address, error, errno, strerror(errno)); + close(server_info->fd); + snmp_log(LOG_ERR, + "server init_server closing socket errno: (%d) (%s)\n", + errno, strerror(errno)); + return DEFAULT_ERROR; + } + error = bind(server_info->fd, (const struct sockaddr *)&addr_4, + sizeof(addr_4)); + break; + } + //When address is IPv6 + case AF_INET6: + { + struct sockaddr_in6 addr_6; + addr_6.sin6_family = AF_INET6; + addr_6.sin6_port = htons(server_info->port); + error = inet_pton(AF_INET6, server_info->address, + &(addr_6.sin6_addr)); + if(error <= DEFAULT_SUCCESS){ + snmp_log(LOG_ERR, "server init_server inet_pton error ip" + "address %s with error: %d errno: (%d) (%s)\n", + server_info->address, error, errno, strerror(errno)); + close(server_info->fd); + snmp_log(LOG_ERR, "server init_server closing socket errno:" + "(%d) (%s)\n", errno, strerror(errno)); + return DEFAULT_ERROR; + } + error = bind(server_info->fd, (const struct sockaddr *)&addr_6, + sizeof(addr_6)); + break; + } + //Should never get here, needed for completeness + default: + { + snmp_log(LOG_ERR, "server init_server run default state %d\n", + server_info -> address_family); + close(server_info->fd); + snmp_log(LOG_ERR, "server init_server closing socket errno:" + "(%d) (%s)\n", errno, strerror(errno)); + return DEFAULT_ERROR; + } + } + + if (error != DEFAULT_SUCCESS) { + snmp_log(LOG_ERR, "server init_server binding errno: (%d) (%s)\n", + errno, strerror(errno)); + close(server_info->fd); + snmp_log(LOG_ERR, "server init_server closing socket errno:" + "(%d) (%s)\n", errno, strerror(errno)); + return DEFAULT_ERROR; + } + + snmp_log(LOG_INFO, "server init_server bind success address: %s with " + "port: %d\n", server_info->address, server_info->port); + error = listen(server_info->fd, BACKLOG); + if (error != DEFAULT_SUCCESS) { + snmp_log(LOG_ERR, "server init_server listen fd:(%d) error, errno:" + " (%d) (%s)\n", server_info->fd, errno, strerror(errno)); + close(server_info->fd); + snmp_log(LOG_ERR, "server init_server closing socket errno: " + "(%d) (%s)\n", errno, strerror(errno)); + return DEFAULT_ERROR; + } + snmp_log(LOG_INFO, "server listening fd: %d \n", server_info->fd); + snmp_log(LOG_INFO, "server init_server success\n"); + return DEFAULT_SUCCESS; +} + +/* +This procedure returns a ServerInfo with host_name and port. Also with all +metadata needed to start listening. In case of error returns NULL. +*/ +ServerInfo get_server_info(const char * host_name, int port){ + + struct addrinfo hints; + struct addrinfo *result, *rp; + struct in_addr in4addr_any; + int error = -1; + ServerInfo server_info; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + hints.ai_protocol = 0; + hints.ai_canonname = NULL; + hints.ai_addr = NULL; + hints.ai_next = NULL; + + snmp_log(LOG_INFO, "server get_server_info for hostname: %s\n", host_name); + error = getaddrinfo(host_name, NULL, &hints, &result); + if (error != 0) { + snmp_log(LOG_ERR, "server get_server_info getaddrinfo: %s\n", + gai_strerror(error)); + return NULL; + } + + server_info = malloc(sizeof(struct sServerInfo)); + if(server_info == NULL){ + snmp_log(LOG_ERR, "server get_server_info error allocation ServerInfo \n"); + freeaddrinfo(result); + result = NULL; + return NULL; + } + + server_info -> port = port; + server_info -> error = DEFAULT_SUCCESS; + server_info -> retries = RETRIES; + + for (rp = result; rp != NULL; rp = rp->ai_next) { + if(rp->ai_family == AF_INET) { + in4addr_any.s_addr = INADDR_ANY; + inet_ntop(AF_INET, &in4addr_any, + server_info->address, sizeof(server_info->address)); + server_info->address_family = AF_INET; + snmp_log(LOG_INFO, "server get_server_info found IPv4: %s\n", + server_info->address); + break; + } else if (rp->ai_family == AF_INET6) { + inet_ntop(AF_INET6, &in6addr_any, + server_info->address, sizeof(server_info->address)); + server_info->address_family = AF_INET6; + snmp_log(LOG_INFO, "server get_server_info found IPv6: %s \n", + server_info->address); + break; + } + } + + if(rp == NULL){ + snmp_log(LOG_ERR, "server get_server_info ip not found at %s\n", + host_name); + free(server_info); + server_info = NULL; + } + + freeaddrinfo(result); + result = NULL; + return server_info; +} + +/* +This procedure intents to close the listener socket of the server and free the +memory of ServerInfo. In case of error returns an non-zero value. +*/ +int stop_alarm_server(ServerInfo server_info){ + assert(server_info!=NULL); + int error = close(server_info->fd); + snmp_log(LOG_ERR, "server stop_alarm_server close errno: (%d) (%s)\n", + errno, strerror(errno)); + free(server_info); + return error; +} + +/* +This procedures is responsible to listen for new connections. +On error stops listening and return a non-zero value. +*/ +int handle_server_messages(ServerInfo server_info){ + + int socket_keep_running = 1; + struct sockaddr cli; + int connfd = 0; + int read = 0; + int bytes_read = 0; + socklen_t cli_len= sizeof(cli); + int length_bytes = 0; + uint32_t length = 0; + uint32_t nlength = 0; + int error_msg_len = DEFAULT_SUCCESS; + int error_processing = DEFAULT_ERROR; + int partial_retries = 0; + int terminate = 0; + + // reduce recall tries and check if max retries reached + server_info->retries = server_info->retries -1; + if(server_info->retries < 0 ){ + snmp_log(LOG_ERR,"server handle_server_messages handling messages MAX" + "retries reach\n"); + return DEFAULT_ERROR; + } + + // start handling messages + snmp_log(LOG_INFO,"server handle_server_messages start handling messages\n"); + snmp_log(LOG_INFO,"server handle_server_messages retries counter: %d\n", + server_info->retries); + + while (socket_keep_running) { + // accepts connections + connfd = accept(server_info->fd, (struct sockaddr*) &cli, &cli_len); + if (connfd < DEFAULT_SUCCESS) { + snmp_log(LOG_ERR,"server handle_server_messages acccept error, errno:" + "(%d) (%s)\n", errno, strerror(errno)); + continue; + } + else{ + snmp_log(LOG_INFO,"server handle_server_messages client socket" + " accepted %d\n", connfd); + } + + // message length read + length_bytes = 0; + nlength = 0; + error_msg_len = DEFAULT_SUCCESS; + partial_retries = 0; + while (length_bytes < MSG_SIZE) { + read = recv(connfd, ((char *)&nlength) + length_bytes, MSG_SIZE - length_bytes, 0); + if (read < DEFAULT_SUCCESS) { + snmp_log(LOG_ERR, + "\nserver handle_server_messages failed to receive message " + "length errno: (%d) (%s)\n", + errno, strerror(errno)); + error_msg_len = DEFAULT_ERROR; + break; + } + + if (partial_retries > RETRIES_MESSAGE_SIZE) { + snmp_log(LOG_ERR,"server handle_server_messages message length " + "max retries: (%d)\n", partial_retries); + error_msg_len = DEFAULT_ERROR; + break; + }else{ + partial_retries ++; + } + + length_bytes += read; + } + + // if error in message len read then recall + if(error_msg_len != DEFAULT_SUCCESS) { + snmp_log(LOG_ERR,"server handle_server_messages recall because handle" + " message len failed\n"); + close(connfd); + snmp_log(LOG_ERR,"server handle_server_messages port close errno: " + "(%d) (%s)\n", errno, strerror(errno)); + terminate = handle_server_messages(server_info); + if(terminate == DEFAULT_ERROR){ + snmp_log(LOG_ERR,"server handle_server_messages recall failed" + " with state %d \n", terminate); + break; + } + } + + // message allocation memory + length = ntohl(nlength); + char *msg = malloc(length); + + // memory allocation error + if(msg == NULL) { + snmp_log(LOG_ERR,"server handle_server_messages recall because " + "message malloc failed\n"); + close(connfd); + snmp_log(LOG_ERR,"server handle_server_messages port close errno:" + " (%d) (%s)\n", + errno, strerror(errno)); + terminate = handle_server_messages(server_info); + if(terminate == DEFAULT_ERROR){ + snmp_log(LOG_ERR,"server handle_server_messages recall failed" + " with state %d \n", terminate); + break; + } + } + + // message read + bytes_read = recv(connfd, msg, length, 0); + + // no message arrived + if (bytes_read < DEFAULT_SUCCESS) { + free(msg); + msg = NULL; + snmp_log(LOG_ERR,"server handle_server_messages recall because" + " message receive failed\n"); + close(connfd); + snmp_log(LOG_ERR,"server handle_server_messages port close errno:" + " (%d) (%s)\n", errno, strerror(errno)); + terminate = handle_server_messages(server_info); + if(terminate == DEFAULT_ERROR){ + snmp_log(LOG_ERR,"server handle_server_messages recall failed" + " with state %d \n", terminate); + break; + } + } + + // error message incomplete + if (bytes_read != length) { + free(msg); + msg = NULL; + snmp_log(LOG_ERR, + "server handle_server_messages recall because message bytes_read" + " != length failed\n"); + close(connfd); + snmp_log(LOG_ERR,"server handle_server_messages port close errno: " + "(%d) (%s)\n", errno, strerror(errno)); + terminate = handle_server_messages(server_info); + if(terminate == DEFAULT_ERROR){ + snmp_log(LOG_ERR,"server handle_server_messages recall failed " + "with state %d \n", terminate); + break; + } + } + + // process the message + error_processing = process_json_alarm(msg); + if(error_processing != DEFAULT_SUCCESS){ + snmp_log(LOG_ERR,"server handle_server_messages bad message " + "processing.\n"); + } + + // free resources + free(msg); + msg = NULL; + close(connfd); + snmp_log(LOG_INFO,"server handle_server_messages port close fd: (%d)," + " errno: (%d) (%s)\n", connfd, errno, strerror(errno)); + snmp_log(LOG_INFO,"server handle_server_messages message received ok.\n\n"); + } + + // if breaks return error + snmp_log(LOG_ERR,"server handle_server_messages unespected error\n"); + return DEFAULT_ERROR; +} + +/* +This procedure starts the server workflow. +In case of memory allocation failure returns NULL. +In case of communication errors returns a ServerInfo with an error +that can be retrieved by get_error() method. +*/ +ServerInfo start_alarm_server (int port){ + ServerInfo server_info = get_server_info(HOST_NAME, port); + int error = DEFAULT_ERROR; + if( server_info != NULL){ + error = init_server(server_info); + if(error == DEFAULT_SUCCESS){ + error = handle_server_messages(server_info); + if (error != DEFAULT_SUCCESS){ + // unespected server error + // retry until MAX tries + server_info -> error = DEFAULT_ERROR; + snmp_log(LOG_ERR, + "server start_alarm_server stopped by error in " + "handle_server_messages\n"); + } + }else{ + // an error during starting up + server_info -> error = DEFAULT_ERROR; + snmp_log(LOG_ERR, "server start_alarm_server stopped by error " + "in init_server\n"); + } + }else{ + // cannot get host address info + snmp_log(LOG_ERR, "server start_alarm_server stopped by error in " + "get_server_info\n"); + } + return server_info; +} diff --git a/stx-snmp-helm/centos/docker/stx-fm-trap-subagent/src/wrsAlarmMIBServer.h b/stx-snmp-helm/centos/docker/stx-fm-trap-subagent/src/wrsAlarmMIBServer.h new file mode 100644 index 0000000..1cd1587 --- /dev/null +++ b/stx-snmp-helm/centos/docker/stx-fm-trap-subagent/src/wrsAlarmMIBServer.h @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2021 Wind River Systems, Inc. +* +* SPDX-License-Identifier: Apache-2.0 +* +*/ + +#ifndef WRSALARMMIBSERVER_H +#define WRSALARMMIBSERVER_H + +typedef struct sServerInfo * ServerInfo; + + +/* +Description: start listening in an specified port. +Parameters: an integer port to start listening +Return value: On error a NULL value if a memory allocation error occurs. + On success a ServerInfo with the runtime information. +*/ +ServerInfo start_alarm_server (int port); + + +/* +Description: stop listening for connections and free memory structures. +Parameters: a ServerInfo not null value. +Return value: a non-zero value on close port error. +*/ +int stop_alarm_server(ServerInfo server_info); + + +/* +Description: retrieve the ServerInfo status. +Parameters: a ServerInfo not null value . +Return value: retrieves non-zero value indicating error status. +*/ +int get_error(ServerInfo server_info); + + +#endif /* WRSALARMMIBSERVER_H */ \ No newline at end of file diff --git a/stx-snmp-helm/centos/docker/stx-fm-trap-subagent/src/wrsAlarmMIBSubagent.c b/stx-snmp-helm/centos/docker/stx-fm-trap-subagent/src/wrsAlarmMIBSubagent.c index d6f9306..66b9d57 100644 --- a/stx-snmp-helm/centos/docker/stx-fm-trap-subagent/src/wrsAlarmMIBSubagent.c +++ b/stx-snmp-helm/centos/docker/stx-fm-trap-subagent/src/wrsAlarmMIBSubagent.c @@ -1,44 +1,18 @@ /* -* Copyright (c) 2020 Wind River Systems, Inc. +* Copyright (c) 2020-2021 Wind River Systems, Inc. * * SPDX-License-Identifier: Apache-2.0 * */ -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include - #include #include #include - #include +#include "wrsAlarmMIBServer.h" -#include "wrsAlarmMIBTrap.h" - -#define MSG_SIZE 4 #define TCP_SOCKET_PORT 162 -#define ALARM_CRITICAL "wrsAlarmCritical" -#define ALARM_MAJOR "wrsAlarmMajor" -#define ALARM_MINOR "wrsAlarmMinor" -#define ALARM_WARNING "wrsAlarmWarning" -#define ALARM_MSG "wrsAlarmMessage" -#define ALARM_CLEAR "wrsAlarmClear" -#define ALARM_HIERARCHICAL_CLEAR "wrsAlarmHierarchicalClear" -#define WARM_START "warmStart" - -#define SA struct sockaddr /* * If compiling within the net-snmp source code, this will trigger the feature @@ -77,131 +51,6 @@ static void usage(void) "\t-L\tDo not open a log file; print all messages to stderr.\n"); exit(0); } -void initSocketServer(void) -{ - int sockfd, connfd, read, bytes_read; - int enable = 1; - int socket_keep_running = 1; - socklen_t len; - struct sockaddr_in servaddr, cli; - const int backlog = 1; - - // socket create and verification - sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (sockfd == -1) { - snmp_log(LOG_ERR,"Socket creation failed\n"); - exit(-1); - } - else - snmp_log(LOG_INFO,"Socket successfully created\n"); - - setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)); - - bzero(&servaddr, sizeof(servaddr)); - - // assign IP, PORT - servaddr.sin_family = AF_INET; - servaddr.sin_addr.s_addr = htonl(INADDR_ANY); - servaddr.sin_port = htons(TCP_SOCKET_PORT); - - // Binding newly created socket to given IP and verification - if ((bind(sockfd, (SA *)&servaddr, sizeof(servaddr))) != 0) { - close(sockfd); - snmp_log(LOG_ERR,"Socket bind failed\n"); - exit(-1); - } - else - snmp_log(LOG_INFO,"Socket successfully binded\n"); - - if ((listen(sockfd, backlog)) != 0) { - snmp_log(LOG_ERR,"Failed to start server socket listen.\n"); - close(sockfd); - exit(-1); - } - else { - snmp_log(LOG_INFO,"Server listening\n"); - } - - len = sizeof(cli); - - while (socket_keep_running) { - connfd = accept(sockfd, (SA *)&cli, &len); - if (connfd < 0) { - snmp_log(LOG_ERR,"Server acccept failed\n"); - close(sockfd); - exit(-1); - } - else - snmp_log(LOG_INFO,"Client socket accepted\n"); - - int length_bytes = 0; - uint32_t length, nlength; - - while (length_bytes < MSG_SIZE) { - read = recv(connfd, ((char *)&nlength) + length_bytes, MSG_SIZE - length_bytes, 0); - if (read == -1) { - snmp_log(LOG_ERR,"Failed to receive message.\n"); - } - length_bytes += read; - } - - length = ntohl(nlength); - char *msg = malloc(length); - bytes_read = recv(connfd, msg, length, 0); - - if (bytes_read == -1) { - snmp_log(LOG_ERR,"Failed to receive message.\n"); - } - - if (bytes_read != length) { - snmp_log(LOG_ERR,"recv: Premature EOF.\n"); - } - - struct json_object *parsed_json = json_tokener_parse(msg); - struct json_object *operation_type; - json_object_object_get_ex(parsed_json, "operation_type", &operation_type); - const char *opt_type = json_object_get_string(operation_type); - - if (strcmp(ALARM_CLEAR, opt_type) == 0) { - - send_wrsAlarmClear_trap(parsed_json); - } - else if (strcmp(ALARM_HIERARCHICAL_CLEAR, opt_type) == 0) { - - send_wrsAlarmHierarchicalClear_trap(parsed_json); - } - else if (strcmp(ALARM_MSG, opt_type) == 0) { - - send_wrsEventMessage_trap(parsed_json); - } - else if (strcmp(ALARM_WARNING, opt_type) == 0) { - - send_wrsAlarmWarning_trap(parsed_json); - } - else if (strcmp(ALARM_MINOR, opt_type) == 0) { - - send_wrsAlarmMinor_trap(parsed_json); - } - else if (strcmp(ALARM_MAJOR, opt_type) == 0) { - - send_wrsAlarmMajor_trap(parsed_json); - } - else if (strcmp(ALARM_CRITICAL, opt_type) == 0) { - - send_wrsAlarmCritical_trap(parsed_json); - } - else if (strcmp(WARM_START, opt_type) == 0) { - - send_wrsWarmStart_trap(); - } - else { - send_wrsAlarmMessage_trap(parsed_json); - } - json_object_put(parsed_json); - free(msg); - } - close(sockfd); -} int main(int argc, char **argv) { @@ -211,6 +60,8 @@ int main(int argc, char **argv) extern char *optarg; int dont_fork = 0, use_syslog = 0; char *agentx_socket = NULL; + ServerInfo server_info = NULL; + int server_info_error = -1; while ((ch = getopt(argc, argv, "D:fHLM-:x:")) != EOF) switch (ch) { @@ -318,7 +169,31 @@ int main(int argc, char **argv) keep_running = 1; signal(SIGTERM, stop_server); signal(SIGINT, stop_server); - initSocketServer(); + + // server start listening + server_info = start_alarm_server(TCP_SOCKET_PORT); + + // if server stops + if(server_info == NULL){ + // server memmory allocation errors + snmp_log(LOG_ERR, "trap-subagent: stopping server, server_info NULL calling stop_server()\n"); + stop_server(SIGABRT); + }else{ + // other server errors + server_info_error = get_error(server_info); + snmp_log(LOG_ERR, "trap-subagent: stopping server, server_info -> error: " + "%d \n", server_info_error); + // if error after closing + if(stop_alarm_server(server_info) < 0){ + snmp_log(LOG_INFO, "trap-subagent: stop server failed %d\n", server_info_error); + }else{ + snmp_log(LOG_INFO, "trap-subagent: stop server success\n"); + } + // server_info to NULL + server_info = NULL; + stop_server(SIGABRT); + } + while (keep_running) { /* if you use select(), see snmp_select_info() in snmp_api(3) */ /* --- OR --- */ @@ -326,7 +201,21 @@ int main(int argc, char **argv) } /* at shutdown time */ + snmp_shutdown("wrsAlarmMIB"); + + if(server_info != NULL){ + // stop from SIGTERM or SIGINT + snmp_log(LOG_INFO, "trap-subagent: signal received, calling stop_alarm_sever()\n"); + server_info_error = get_error(server_info); + if( stop_alarm_server(server_info) < 0 ){ + snmp_log(LOG_INFO, "trap-subagent: stop server error: %d\n", server_info_error); + }else{ + snmp_log(LOG_INFO, "trap-subagent: stop server success\n"); + } + server_info = NULL; + } + SOCK_CLEANUP; exit(0); } diff --git a/stx-snmp-helm/centos/docker/stx-fm-trap-subagent/src/wrsAlarmMIBTrap.c b/stx-snmp-helm/centos/docker/stx-fm-trap-subagent/src/wrsAlarmMIBTrap.c index 711d56a..1b446a8 100644 --- a/stx-snmp-helm/centos/docker/stx-fm-trap-subagent/src/wrsAlarmMIBTrap.c +++ b/stx-snmp-helm/centos/docker/stx-fm-trap-subagent/src/wrsAlarmMIBTrap.c @@ -1,11 +1,12 @@ /* -* Copyright (c) 2020 Wind River Systems, Inc. +* Copyright (c) 2020-2021 Wind River Systems, Inc. * * SPDX-License-Identifier: Apache-2.0 * */ #include +#include #include #include @@ -31,6 +32,15 @@ #define EVENT_CAUSE "wrsEventProbableCause" #define EVENT_SERVICE_AFFECTING "wrsEventServiceAffecting" +#define ALARM_CRITICAL "wrsAlarmCritical" +#define ALARM_MAJOR "wrsAlarmMajor" +#define ALARM_MINOR "wrsAlarmMinor" +#define ALARM_WARNING "wrsAlarmWarning" +#define ALARM_MSG "wrsAlarmMessage" +#define ALARM_CLEAR "wrsAlarmClear" +#define ALARM_HIERARCHICAL_CLEAR "wrsAlarmHierarchicalClear" +#define WARM_START "warmStart" + extern const oid snmptrap_oid[]; extern const size_t snmptrap_oid_len; @@ -894,4 +904,51 @@ send_wrsWarmStart_trap() snmp_free_varbind( var_list ); return SNMP_ERR_NOERROR; +} + +int +process_json_alarm(const char* msg ) +{ + + if(msg == NULL) { + snmp_log(LOG_ERR,"JSON message alarm to processs is null\n"); + return 1; + } + + struct json_object *parsed_json = json_tokener_parse(msg); + struct json_object *operation_type; + json_object_object_get_ex(parsed_json, "operation_type", &operation_type); + const char *opt_type = json_object_get_string(operation_type); + + if (strcmp(ALARM_CLEAR, opt_type) == 0) { + send_wrsAlarmClear_trap(parsed_json); + } + else if (strcmp(ALARM_HIERARCHICAL_CLEAR, opt_type) == 0) { + send_wrsAlarmHierarchicalClear_trap(parsed_json); + } + else if (strcmp(ALARM_MSG, opt_type) == 0) { + send_wrsEventMessage_trap(parsed_json); + } + else if (strcmp(ALARM_WARNING, opt_type) == 0) { + send_wrsAlarmWarning_trap(parsed_json); + } + else if (strcmp(ALARM_MINOR, opt_type) == 0) { + send_wrsAlarmMinor_trap(parsed_json); + } + else if (strcmp(ALARM_MAJOR, opt_type) == 0) { + send_wrsAlarmMajor_trap(parsed_json); + } + else if (strcmp(ALARM_CRITICAL, opt_type) == 0) { + send_wrsAlarmCritical_trap(parsed_json); + } + else if (strcmp(WARM_START, opt_type) == 0) { + send_wrsWarmStart_trap(); + } + else { + send_wrsAlarmMessage_trap(parsed_json); + } + + json_object_put(parsed_json); + + return 0; } \ No newline at end of file diff --git a/stx-snmp-helm/centos/docker/stx-fm-trap-subagent/src/wrsAlarmMIBTrap.h b/stx-snmp-helm/centos/docker/stx-fm-trap-subagent/src/wrsAlarmMIBTrap.h index 9b9045f..49566bc 100644 --- a/stx-snmp-helm/centos/docker/stx-fm-trap-subagent/src/wrsAlarmMIBTrap.h +++ b/stx-snmp-helm/centos/docker/stx-fm-trap-subagent/src/wrsAlarmMIBTrap.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2020 Wind River Systems, Inc. +* Copyright (c) 2020-2021 Wind River Systems, Inc. * * SPDX-License-Identifier: Apache-2.0 * @@ -19,5 +19,6 @@ int send_wrsEventMessage_trap(struct json_object *); int send_wrsAlarmClear_trap(struct json_object *); int send_wrsAlarmHierarchicalClear_trap(struct json_object *); int send_wrsWarmStart_trap(void); +int process_json_alarm(const char* msg); #endif /* WRSALARMMIBTRAP_H */