📄 snmp_pdu.c
字号:
/* * SNMP PDU Encoding * * Complies with: * * RFC 1902: Structure of Management Information for SNMPv2 * *//********************************************************************** * * Copyright 1997 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. * * Author: Ryan Troll <ryan+@andrew.cmu.edu> * **********************************************************************/#include "config.h"#include <stdio.h>#if HAVE_UNISTD_H#include <unistd.h>#endif#if HAVE_STDLIB_H#include <stdlib.h>#endif#if HAVE_SYS_TYPES_H#include <sys/types.h>#endif#if HAVE_CTYPE_H#include <ctype.h>#endif#if HAVE_GNUMALLOC_H#include <gnumalloc.h>#elif HAVE_MALLOC_H && !defined(_SQUID_FREEBSD_) && !defined(_SQUID_NEXT_)#include <malloc.h>#endif#if HAVE_MEMORY_H#include <memory.h>#endif#ifdef HAVE_STRING_H#include <string.h>#endif#ifdef HAVE_STRINGS_H#include <strings.h>#endif#if HAVE_BSTRING_H#include <bstring.h>#endif#if HAVE_SYS_SOCKET_H#include <sys/socket.h>#endif#if HAVE_NETINET_IN_H#include <netinet/in.h>#endif#if HAVE_ARPA_INET_H#include <arpa/inet.h>#endif#if HAVE_SYS_TIME_H#include <sys/time.h>#endif#if HAVE_NETDB_H#include <netdb.h>#endif#include "snmp.h"#include "asn1.h"#include "snmp_error.h"#include "snmp_vars.h"#include "snmp_pdu.h"#include "snmp_msg.h"#include "snmp_api_error.h"#include "util.h"/* #define DEBUG_PDU 1 *//* #define DEBUG_PDU_DECODE 1 *//* #define DEBUG_PDU_ENCODE 1 */#define ASN_PARSE_ERROR(x) { return(x); }/**********************************************************************//* Create a PDU. */struct snmp_pdu *snmp_pdu_create(int command){ struct snmp_pdu *pdu;#ifdef DEBUG_PDU snmplib_debug(8, "PDU: Creating\n");#endif pdu = (struct snmp_pdu *) xmalloc(sizeof(struct snmp_pdu)); if (pdu == NULL) { snmp_set_api_error(SNMPERR_OS_ERR); return (NULL); } memset((char *) pdu, '\0', sizeof(struct snmp_pdu)); pdu->command = command; pdu->errstat = SNMP_DEFAULT_ERRSTAT; pdu->errindex = SNMP_DEFAULT_ERRINDEX; pdu->address.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS; pdu->enterprise = NULL; pdu->enterprise_length = 0; pdu->variables = NULL;#ifdef DEBUG_PDU snmplib_debug(8, "PDU: Created %x\n", (unsigned int) pdu);#endif return (pdu);}/**********************************************************************//* Clone an existing PDU. */struct snmp_pdu *snmp_pdu_clone(struct snmp_pdu *Src){ struct snmp_pdu *Dest;#ifdef DEBUG_PDU snmplib_debug(8, "PDU %x: Cloning\n", (unsigned int) Src);#endif Dest = (struct snmp_pdu *) xmalloc(sizeof(struct snmp_pdu)); if (Dest == NULL) { snmp_set_api_error(SNMPERR_OS_ERR); return (NULL); } xmemcpy((char *) Dest, (char *) Src, sizeof(struct snmp_pdu));#ifdef DEBUG_PDU snmplib_debug(8, "PDU %x: Created %x\n", (unsigned int) Src, (unsigned int) Dest);#endif return (Dest);}/**********************************************************************//* * If there was an error in the input pdu, creates a clone of the pdu * that includes all the variables except the one marked by the errindex. * The command is set to the input command and the reqid, errstat, and * errindex are set to default values. * If the error status didn't indicate an error, the error index didn't * indicate a variable, the pdu wasn't a get response message, or there * would be no remaining variables, this function will return NULL. * If everything was successful, a pointer to the fixed cloned pdu will * be returned. */struct snmp_pdu *snmp_pdu_fix(struct snmp_pdu *pdu, int command){ return (snmp_fix_pdu(pdu, command));}struct snmp_pdu *snmp_fix_pdu(struct snmp_pdu *pdu, int command){ struct variable_list *var, *newvar; struct snmp_pdu *newpdu; int index; int copied = 0;#ifdef DEBUG_PDU snmplib_debug(8, "PDU %x: Fixing. Err index is %d\n", (unsigned int) pdu, (unsigned int) pdu->errindex);#endif if (pdu->command != SNMP_PDU_RESPONSE || pdu->errstat == SNMP_ERR_NOERROR || pdu->errindex <= 0) { snmp_set_api_error(SNMPERR_UNABLE_TO_FIX); return (NULL); } /* clone the pdu */ newpdu = snmp_pdu_clone(pdu); if (newpdu == NULL) return (NULL); newpdu->variables = 0; newpdu->command = command; newpdu->reqid = SNMP_DEFAULT_REQID; newpdu->errstat = SNMP_DEFAULT_ERRSTAT; newpdu->errindex = SNMP_DEFAULT_ERRINDEX; /* Loop through the variables, removing whatever isn't necessary */ var = pdu->variables; index = 1; /* skip first variable if necessary */ if (pdu->errindex == index) { var = var->next_variable; index++; } if (var != NULL) { /* VAR is the first uncopied variable */ /* Clone this variable */ newpdu->variables = snmp_var_clone(var); if (newpdu->variables == NULL) { snmp_pdu_free(newpdu); return (NULL); } copied++; newvar = newpdu->variables; /* VAR has been copied to NEWVAR. */ while (var->next_variable) { /* Skip the item that was bad */ if (++index == pdu->errindex) { var = var->next_variable; continue; } /* Copy this var */ newvar->next_variable = snmp_var_clone(var->next_variable); if (newvar->next_variable == NULL) { snmp_pdu_free(newpdu); return (NULL); } /* Move to the next one */ newvar = newvar->next_variable; var = var->next_variable; copied++; } newvar->next_variable = NULL; } /* If we didn't copy anything, free the new pdu. */ if (index < pdu->errindex || copied == 0) { snmp_free_pdu(newpdu); snmp_set_api_error(SNMPERR_UNABLE_TO_FIX); return (NULL); }#ifdef DEBUG_PDU snmplib_debug(8, "PDU %x: Fixed PDU is %x\n", (unsigned int) pdu, (unsigned int) newpdu);#endif return (newpdu);}/**********************************************************************/void snmp_pdu_free(struct snmp_pdu *pdu){ snmp_free_pdu(pdu);}/* * Frees the pdu and any xmalloc'd data associated with it. */void snmp_free_pdu(struct snmp_pdu *pdu){ struct variable_list *vp, *ovp; vp = pdu->variables; while (vp) { ovp = vp; vp = vp->next_variable; snmp_var_free(ovp); } if (pdu->enterprise) xfree((char *) pdu->enterprise); xfree((char *) pdu);}/**********************************************************************//* Encode this PDU into DestBuf. * * Returns a pointer to the next byte in the buffer (where the Variable * Bindings belong.) *//* * RFC 1902: Structure of Management Information for SNMPv2 * * PDU ::= * SEQUENCE { * request-id INTEGER32 * error-status INTEGER * error-index INTEGER * Variable Bindings * } * * BulkPDU ::= * SEQUENCE { * request-id INTEGER32 * non-repeaters INTEGER * max-repetitions INTEGER * Variable Bindings * } *//* * RFC 1157: A Simple Network Management Protocol (SNMP) * * PDU ::= * SEQUENCE { * request-id INTEGER * error-status INTEGER * error-index INTEGER * Variable Bindings * } * * TrapPDU ::= * SEQUENCE { * enterprise NetworkAddress * generic-trap INTEGER * specific-trap INTEGER * time-stamp TIMETICKS * Variable Bindings * } */u_char *snmp_pdu_encode(u_char * DestBuf, int *DestBufLen,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -