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 <pablo.bovina@windriver.com> Change-Id: I89b1d8e7c97d315637b12bcfea0269f2fcf8d452
This commit is contained in:
parent
f15426c720
commit
5aca0dd166
@ -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)
|
||||
|
||||
|
@ -0,0 +1,444 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Wind River Systems, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
*/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <json-c/json.h>
|
||||
#include <netdb.h>
|
||||
#include <net-snmp/net-snmp-config.h>
|
||||
#include <net-snmp/net-snmp-includes.h>
|
||||
#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;
|
||||
}
|
@ -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 */
|
@ -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 <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <json-c/json.h>
|
||||
#include <netdb.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <net-snmp/net-snmp-config.h>
|
||||
#include <net-snmp/net-snmp-features.h>
|
||||
#include <net-snmp/net-snmp-includes.h>
|
||||
|
||||
#include <net-snmp/agent/net-snmp-agent-includes.h>
|
||||
#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);
|
||||
}
|
||||
|
@ -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 <net-snmp/net-snmp-config.h>
|
||||
#include <net-snmp/net-snmp-features.h>
|
||||
#include <net-snmp/net-snmp-includes.h>
|
||||
#include <net-snmp/agent/net-snmp-agent-includes.h>
|
||||
|
||||
@ -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;
|
||||
}
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user