snmptrapd_log.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:55k
- /*
- * snmptrapd_log.c - format SNMP trap information for logging
- *
- */
- /*****************************************************************
- Copyright 1989, 1991, 1992 by Carnegie Mellon University
- All Rights Reserved
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted,
- provided that the above copyright notice appear in all copies and that
- both that copyright notice and this permission notice appear in
- supporting documentation, and that the name of CMU not be
- used in advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
- CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- CMU BE LIABLE FOR ANY SPECIAL, 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 <net-snmp/net-snmp-config.h>
- #if HAVE_STDLIB_H
- #include <stdlib.h>
- #endif
- #if HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #if HAVE_STRING_H
- #include <string.h>
- #else
- #include <strings.h>
- #endif
- #include <sys/types.h>
- #if HAVE_SYS_WAIT_H
- #include <sys/wait.h>
- #endif
- #if HAVE_WINSOCK_H
- #include <winsock.h>
- #else
- #include <sys/socket.h>
- #endif
- #if HAVE_SYS_SOCKIO_H
- #include <sys/sockio.h>
- #endif
- #if HAVE_NETINET_IN_H
- #include <netinet/in.h>
- #endif
- #include <stdio.h>
- #include <ctype.h>
- #if HAVE_SYS_TIME_H
- # include <sys/time.h>
- # if TIME_WITH_SYS_TIME
- # include <time.h>
- # endif
- #else
- # include <time.h>
- #endif
- #if HAVE_SYS_SELECT_H
- #include <sys/select.h>
- #endif
- #if HAVE_SYS_PARAM_H
- #include <sys/param.h>
- #endif
- #if HAVE_SYSLOG_H
- #include <syslog.h>
- #endif
- #if HAVE_SYS_IOCTL_H
- #include <sys/ioctl.h>
- #endif
- #if HAVE_NET_IF_H
- #include <net/if.h>
- #endif
- #if HAVE_NETDB_H
- #include <netdb.h>
- #endif
- #if HAVE_ARPA_INET_H
- #include <arpa/inet.h>
- #endif
- #if HAVE_FCNTL_H
- #include <fcntl.h>
- #endif
- #include <net-snmp/net-snmp-includes.h>
- #include "snmptrapd_log.h"
- #ifndef BSD4_3
- #define BSD4_2
- #endif
- /*
- * These flags mark undefined values in the options structure
- */
- #define UNDEF_CMD '*'
- #define UNDEF_PRECISION -1
- /*
- * This structure holds the options for a single format command
- */
- typedef struct {
- char cmd; /* the format command itself */
- size_t width; /* the field's minimum width */
- size_t precision; /* the field's precision */
- int left_justify; /* if true, left justify this field */
- int alt_format; /* if true, display in alternate format */
- int leading_zeroes; /* if true, display with leading zeroes */
- } options_type;
- char separator[32];
- /*
- * These symbols define the characters that the parser recognizes.
- * The rather odd choice of symbols comes from an attempt to avoid
- * colliding with the ones that printf uses, so that someone could add
- * printf functionality to this code and turn it into a library
- * routine in the future.
- */
- typedef enum {
- CHR_FMT_DELIM = '%', /* starts a format command */
- CHR_LEFT_JUST = '-', /* left justify */
- CHR_LEAD_ZERO = '0', /* use leading zeroes */
- CHR_ALT_FORM = '#', /* use alternate format */
- CHR_FIELD_SEP = '.', /* separates width and precision fields */
- CHR_CUR_TIME = 't', /* current time, Unix format */
- CHR_CUR_YEAR = 'y', /* current year */
- CHR_CUR_MONTH = 'm', /* current month */
- CHR_CUR_MDAY = 'l', /* current day of month */
- CHR_CUR_HOUR = 'h', /* current hour */
- CHR_CUR_MIN = 'j', /* current minute */
- CHR_CUR_SEC = 'k', /* current second */
- CHR_UP_TIME = 'T', /* uptime, Unix format */
- CHR_UP_YEAR = 'Y', /* uptime year */
- CHR_UP_MONTH = 'M', /* uptime month */
- CHR_UP_MDAY = 'L', /* uptime day of month */
- CHR_UP_HOUR = 'H', /* uptime hour */
- CHR_UP_MIN = 'J', /* uptime minute */
- CHR_UP_SEC = 'K', /* uptime second */
- CHR_AGENT_IP = 'a', /* agent's IP address */
- CHR_AGENT_NAME = 'A', /* agent's host name if available */
- CHR_PDU_IP = 'b', /* PDU's IP address */
- CHR_PDU_NAME = 'B', /* PDU's host name if available */
- CHR_PDU_ENT = 'N', /* PDU's enterprise string */
- CHR_PDU_WRAP = 'P', /* PDU's wrapper info (community, security) */
- CHR_TRAP_NUM = 'w', /* trap number */
- CHR_TRAP_DESC = 'W', /* trap's description (textual) */
- CHR_TRAP_STYPE = 'q', /* trap's subtype */
- CHR_TRAP_VARSEP = 'V', /* character (or string) to separate variables */
- CHR_TRAP_VARS = 'v' /* tab-separated list of trap's variables */
- } parse_chr_type;
- /*
- * These symbols define the states for the parser's state machine
- */
- typedef enum {
- PARSE_NORMAL, /* looking for next character */
- PARSE_BACKSLASH, /* saw a backslash */
- PARSE_IN_FORMAT, /* saw a % sign, in a format command */
- PARSE_GET_WIDTH, /* getting field width */
- PARSE_GET_PRECISION, /* getting field precision */
- PARSE_GET_SEPARATOR /* getting field separator */
- } parse_state_type;
- /*
- * macros
- */
- #define is_cur_time_cmd(chr) ((((chr) == CHR_CUR_TIME)
- || ((chr) == CHR_CUR_YEAR)
- || ((chr) == CHR_CUR_MONTH)
- || ((chr) == CHR_CUR_MDAY)
- || ((chr) == CHR_CUR_HOUR)
- || ((chr) == CHR_CUR_MIN)
- || ((chr) == CHR_CUR_SEC)) ? TRUE : FALSE)
- /*
- * Function:
- * Returns true if the character is a format command that outputs
- * some field that deals with the current time.
- *
- * Input Parameters:
- * chr - character to check
- */
- #define is_up_time_cmd(chr) ((((chr) == CHR_UP_TIME)
- || ((chr) == CHR_UP_YEAR)
- || ((chr) == CHR_UP_MONTH)
- || ((chr) == CHR_UP_MDAY)
- || ((chr) == CHR_UP_HOUR)
- || ((chr) == CHR_UP_MIN)
- || ((chr) == CHR_UP_SEC)) ? TRUE : FALSE)
- /*
- * Function:
- * Returns true if the character is a format command that outputs
- * some field that deals with up-time.
- *
- * Input Parameters:
- * chr - character to check
- */
- #define is_agent_cmd(chr) ((((chr) == CHR_AGENT_IP)
- || ((chr) == CHR_AGENT_NAME)) ? TRUE : FALSE)
- /*
- * Function:
- * Returns true if the character outputs information about the
- * agent.
- *
- * Input Parameters:
- * chr - the character to check
- */
- #define is_pdu_ip_cmd(chr) ((((chr) == CHR_PDU_IP)
- || ((chr) == CHR_PDU_NAME)) ? TRUE : FALSE)
- /*
- * Function:
- * Returns true if the character outputs information about the PDU's
- * host name or IP address.
- *
- * Input Parameters:
- * chr - the character to check
- */
- #define is_trap_cmd(chr) ((((chr) == CHR_TRAP_NUM)
- || ((chr) == CHR_TRAP_DESC)
- || ((chr) == CHR_TRAP_STYPE)
- || ((chr) == CHR_TRAP_VARS)) ? TRUE : FALSE)
- /*
- * Function:
- * Returns true if the character outputs information about the trap.
- *
- * Input Parameters:
- * chr - the character to check
- */
- #define is_fmt_cmd(chr) ((is_cur_time_cmd (chr)
- || is_up_time_cmd (chr)
- || is_agent_cmd (chr)
- || is_pdu_ip_cmd (chr)
- || ((chr) == CHR_PDU_ENT)
- || ((chr) == CHR_PDU_WRAP)
- || is_trap_cmd (chr)) ? TRUE : FALSE)
- /*
- * Function:
- * Returns true if the character is a format command.
- *
- * Input Parameters:
- * chr - character to check
- */
- #define is_numeric_cmd(chr) ((is_cur_time_cmd(chr)
- || is_up_time_cmd(chr)
- || (chr) == CHR_TRAP_NUM) ? TRUE : FALSE)
- /*
- * Function:
- * Returns true if this is a numeric format command.
- *
- * Input Parameters:
- * chr - character to check
- */
- #define reference(var) ((var) == (var))
- /*
- * Function:
- * Some compiler options will tell the compiler to be picky and
- * warn you if you pass a parameter to a function but don't use it.
- * This macro lets you reference a parameter so that the compiler won't
- * generate the warning. It has no other effect.
- *
- * Input Parameters:
- * var - the parameter to reference
- */
- /*
- * prototypes
- */
- extern const char *trap_description(int trap);
- static void
- init_options(options_type * options)
- /*
- * Function:
- * Initialize a structure that contains the option settings for
- * a format command.
- *
- * Input Parameters:
- * options - points to the structure to initialize
- */
- {
- /*
- * initialize the structure's fields
- */
- options->cmd = '*';
- options->width = 0;
- options->precision = UNDEF_PRECISION;
- options->left_justify = FALSE;
- options->alt_format = FALSE;
- options->leading_zeroes = FALSE;
- return;
- }
- static int
- realloc_output_temp_bfr(u_char ** buf, size_t * buf_len, size_t * out_len,
- int allow_realloc,
- u_char ** temp_buf, options_type * options)
- /*
- * Function:
- * Append the contents of the temporary buffer to the specified
- * buffer using the correct justification, leading zeroes, width,
- * precision, and other characteristics specified in the options
- * structure.
- *
- * buf, buf_len, out_len, allow_realloc - standard relocatable
- * buffer parameters
- * temp_buf - pointer to string to append onto output buffer. THIS
- * STRING IS free()d BY THIS FUNCTION.
- * options - what options to use when appending string
- */
- {
- size_t temp_len; /* length of temporary buffer */
- size_t temp_to_write; /* # of chars to write from temp bfr */
- size_t char_to_write; /* # of other chars to write */
- size_t zeroes_to_write; /* fill to precision with zeroes for numbers */
- if (temp_buf == NULL || *temp_buf == NULL) {
- return 1;
- }
- /*
- * Figure out how many characters are in the temporary buffer now,
- * and how many of them we'll write.
- */
- temp_len = strlen((char *) *temp_buf);
- temp_to_write = temp_len;
- if (options->precision != UNDEF_PRECISION &&
- temp_to_write > options->precision) {
- temp_to_write = options->precision;
- }
- /*
- * Handle leading characters.
- */
- if ((!options->left_justify) && (temp_to_write < options->width)) {
- zeroes_to_write = options->precision - temp_to_write;
- if (!is_numeric_cmd(options->cmd)) {
- zeroes_to_write = 0;
- }
- for (char_to_write = options->width - temp_to_write;
- char_to_write > 0; char_to_write--) {
- if ((*out_len + 1) >= *buf_len) {
- if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
- *(*buf + *out_len) = ' ';
- free(*temp_buf);
- return 0;
- }
- }
- if (options->leading_zeroes || zeroes_to_write-- > 0) {
- *(*buf + *out_len) = '0';
- } else {
- *(*buf + *out_len) = ' ';
- }
- (*out_len)++;
- }
- }
- /*
- * Truncate the temporary buffer and append its contents.
- */
- *(*temp_buf + temp_to_write) = ' ';
- if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, *temp_buf)) {
- free(*temp_buf);
- return 0;
- }
- /*
- * Handle trailing characters.
- */
- if ((options->left_justify) && (temp_to_write < options->width)) {
- for (char_to_write = options->width - temp_to_write;
- char_to_write > 0; char_to_write--) {
- if ((*out_len + 1) >= *buf_len) {
- if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
- *(*buf + *out_len) = ' ';
- free(*temp_buf);
- return 0;
- }
- }
- *(*buf + *out_len) = '0';
- (*out_len)++;
- }
- }
- /*
- * Slap on a trailing