📄 protocol.c
字号:
#include <config.h>#include <stdio.h>#include <errno.h>#if HAVE_STDLIB_H#include <stdlib.h>#endif#if HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#if HAVE_UNISTD_H#include <unistd.h>#endif#include <sys/types.h>#if TIME_WITH_SYS_TIME# ifdef WIN32# include <sys/timeb.h># else# include <sys/time.h># endif# include <time.h>#else# if HAVE_SYS_TIME_H# include <sys/time.h># else# include <time.h># endif#endif#if HAVE_NETINET_IN_H#include <netinet/in.h>#endif#if HAVE_ARPA_INET_H#include <arpa/inet.h>#endif#if HAVE_WINSOCK_H#include <winsock.h>#endif#include "asn1.h"#include "snmp_api.h"#include "snmp_impl.h"#include "snmp.h"#include "snmp_client.h"#include "snmp_debug.h"#include "mib.h"#include "agentx/protocol.h"int agentx_dump(struct snmp_session *,struct snmp_pdu *, u_char *, size_t);voidagentx_build_int(u_char *bufp, u_int value, int network_byte_order){ if ( network_byte_order ) {#ifndef WORDS_BIGENDIAN value = ntohl( value );#endif memmove( bufp, &value, 4); } else {#ifndef WORDS_BIGENDIAN memmove( bufp, &value, 4);#else *bufp = (u_char)value & 0xff; value >>=8; bufp++; *bufp = (u_char)value & 0xff; value >>=8; bufp++; *bufp = (u_char)value & 0xff; value >>=8; bufp++; *bufp = (u_char)value & 0xff;#endif }}voidagentx_build_short(u_char *bufp, int in_value, int network_byte_order){ u_short value = (u_short)in_value; if ( network_byte_order ) {#ifndef WORDS_BIGENDIAN value = ntohs( value );#endif memmove( bufp, &value, 2); } else {#ifndef WORDS_BIGENDIAN memmove( bufp, &value, 2);#else *bufp = (u_char)value & 0xff; value >>=8; bufp++; *bufp = (u_char)value & 0xff;#endif }}u_char*agentx_build_oid(u_char *bufp, size_t *out_length, int inc, oid *name, size_t name_len, int network_byte_order){ int prefix = 0; size_t i; if ( name_len == 2 && name[0] == 0 && name[1] == 0 ) { name_len = 0; /* NUll OID */ } /* 'Compact' internet OIDs */ if ( name_len >= 5 && name[0] == 1 && name[1] == 3 && name[2] == 6 && name[3] == 1 ) { prefix = name[4]; name += 5; name_len -= 5; } if ( *out_length < 4 + 4*name_len ) return NULL; *bufp = (u_char)name_len; bufp++; *bufp = (u_char)prefix; bufp++; *bufp = (u_char)inc; bufp++; *bufp = 0; bufp++; *out_length -= 4; for ( i = 0 ; i < name_len ; i++ ) { agentx_build_int( bufp, name[i], network_byte_order ); bufp += 4; *out_length -= 4; } return bufp;}u_char*agentx_build_string(u_char *bufp, size_t *out_length, u_char *name, size_t name_len, int network_byte_order){ if ( *out_length < 4 + name_len ) { return NULL; } agentx_build_int( bufp, (u_int)name_len, network_byte_order ); bufp += 4; *out_length -= 4; if ( name_len == 0 ) return bufp; memmove( bufp, name, name_len ); bufp += name_len; *out_length -= name_len; /* Pad to a multiple of 4 bytes */ name_len &= 0x3; if ( name_len ) name_len = 4-name_len; for ( ; name_len ; name_len-- ) { *bufp = 0; bufp++; *out_length--; } return bufp;}u_char*agentx_build_varbind(u_char *bufp, size_t *out_length, struct variable_list *vp, int network_byte_order){ if ( *out_length < 4 ) return NULL; agentx_build_short( bufp, (u_int)vp->type, network_byte_order); bufp +=2; *bufp = 0; bufp++; *bufp = 0; bufp++; /* <reserved> */ *out_length -=4; bufp = agentx_build_oid( bufp, out_length, 0, vp->name, vp->name_length, network_byte_order); if ( bufp == NULL ) return NULL; switch ( (short)vp->type ) { case ASN_INTEGER: case ASN_COUNTER: case ASN_GAUGE: case ASN_TIMETICKS: if ( *out_length < 4 ) return NULL; agentx_build_int( bufp, *(vp->val.integer), network_byte_order); bufp += 4; *out_length -= 4; break; case ASN_OCTET_STR: case ASN_IPADDRESS: case ASN_OPAQUE: bufp = agentx_build_string( bufp, out_length, vp->val.string, vp->val_len, network_byte_order); break; case ASN_OBJECT_ID: bufp = agentx_build_oid( bufp, out_length, 0, vp->val.objid, vp->val_len/4, network_byte_order); break; case ASN_COUNTER64: if ( *out_length < 8 ) return NULL; if ( network_byte_order ) { agentx_build_int( bufp, vp->val.counter64->high, network_byte_order); agentx_build_int( bufp+4, vp->val.counter64->low, network_byte_order); } else { agentx_build_int( bufp, vp->val.counter64->low, network_byte_order); agentx_build_int( bufp+4, vp->val.counter64->high, network_byte_order); } bufp += 8; *out_length -= 8; break; case ASN_NULL: case SNMP_NOSUCHOBJECT: case SNMP_NOSUCHINSTANCE: case SNMP_ENDOFMIBVIEW: break; default: return NULL; } return bufp;}u_char*agentx_build_header(struct snmp_pdu *pdu, u_char *bufp, size_t *out_length){ *bufp = 1; bufp++; /* version */ *bufp = pdu->command; bufp++; /* type */ *bufp = pdu->flags & AGENTX_MSG_FLAGS_MASK; bufp++; /* AgentX flags */ *bufp = 0; bufp++; /* <reserved> */ *out_length -=4; agentx_build_int( bufp, pdu->sessid, pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER ); *out_length -=4; bufp +=4; agentx_build_int( bufp, pdu->transid, pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER ); *out_length -=4; bufp +=4; agentx_build_int( bufp, pdu->reqid, pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER ); *out_length -=4; bufp +=4; agentx_build_int( bufp, 0, 0 ); /* dummy payload length */ *out_length -=4; bufp +=4; if ( pdu->flags & AGENTX_MSG_FLAG_NON_DEFAULT_CONTEXT ) { bufp = agentx_build_string( bufp, out_length, pdu->community, pdu->community_len, pdu->flags & AGENTX_MSG_FLAG_NETWORK_BYTE_ORDER ); } return bufp;}static int_agentx_build(struct snmp_session *session, struct snmp_pdu *pdu, register u_char *packet, size_t *out_length){ u_char *bufp = packet; u_char *prefix_ptr, *range_ptr; size_t length; struct variable_list *vp; int inc; session->s_snmp_errno = 0; session->s_errno = 0; /* Build the header (and context if appropriate) */ if ( *out_length < 20 ) return -1; bufp = agentx_build_header( pdu, bufp, out_length ); if ( bufp == NULL ) return -1; switch ( pdu->command ) { case AGENTX_MSG_OPEN: /* Timeout */ if ( *out_length < 4 ) return -1; *bufp = pdu->time; bufp++; *bufp = 0; bufp++; *bufp = 0; bufp++; *bufp = 0; bufp++; *out_length -= 4; bufp = agentx_build_oid( bufp, out_length, 0, pdu->variables->name, pdu->variables->name_length, pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER); if ( bufp == NULL ) return -1; bufp = agentx_build_string( bufp, out_length, pdu->variables->val.string, pdu->variables->val_len, pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER); if ( bufp == NULL ) return -1; break; case AGENTX_MSG_CLOSE: /* Reason */ if ( *out_length < 4 ) return -1; *bufp = pdu->errstat; bufp++; *bufp = 0; bufp++; *bufp = 0; bufp++; *bufp = 0; bufp++; *out_length -= 4; break; case AGENTX_MSG_REGISTER: case AGENTX_MSG_UNREGISTER: if ( *out_length < 4 ) return -1; *bufp = pdu->time; bufp++; /* Timeout (Register only) */ *bufp = pdu->priority; bufp++; range_ptr = bufp; /* Points to the 'range_subid' field */ *bufp = pdu->range_subid; bufp++; *bufp = 0; bufp++; *out_length -= 4; vp = pdu->variables; prefix_ptr = bufp+1; /* Points to the 'prefix' field */ bufp = agentx_build_oid( bufp, out_length, 0, vp->name, vp->name_length, pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER); if ( bufp == NULL ) return -1; if ( pdu->range_subid ) { if ( *out_length < 4 ) return -1; /* This assumes that the two OIDs match to form a valid range */ agentx_build_int( bufp, vp->val.objid[pdu->range_subid-1], pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER); bufp += 4; *out_length -= 4; /* If the OID has been 'compacted', then tweak the packet's 'range_subid' to reflect this */ if ( *prefix_ptr ) *range_ptr -= 5; } break; case AGENTX_MSG_GETBULK: if ( *out_length < 4 ) return -1; agentx_build_short( bufp , pdu->non_repeaters, pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER); agentx_build_short( bufp+2, pdu->max_repetitions, pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER); bufp += 4; *out_length -= 4; /* Fallthrough */ case AGENTX_MSG_GET: case AGENTX_MSG_GETNEXT: for (vp = pdu->variables; vp ; vp=vp->next_variable ) { inc = ( vp->type == ASN_PRIV_INCL_RANGE ); bufp = agentx_build_oid( bufp, out_length, inc, vp->name, vp->name_length, pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER); if ( bufp == NULL ) return -1; bufp = agentx_build_oid( bufp, out_length, 0, vp->val.objid, vp->val_len/4, pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER); if ( bufp == NULL ) return -1; } break; case AGENTX_MSG_RESPONSE: pdu->flags &= ~(UCD_MSG_FLAG_EXPECT_RESPONSE); if ( *out_length < 4 ) return -1; agentx_build_int( bufp, pdu->time, pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER); bufp += 4; *out_length -= 4; if ( *out_length < 4 ) return -1; agentx_build_short( bufp , pdu->errstat, pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER); agentx_build_short( bufp+2, pdu->errindex, pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER); bufp += 4; *out_length -= 4; /* Fallthrough */ case AGENTX_MSG_INDEX_ALLOCATE: case AGENTX_MSG_INDEX_DEALLOCATE: case AGENTX_MSG_NOTIFY: case AGENTX_MSG_TESTSET: for (vp = pdu->variables; vp ; vp=vp->next_variable ) { bufp = agentx_build_varbind( bufp, out_length, vp, pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER); if ( bufp == NULL ) return -1; } break; case AGENTX_MSG_COMMITSET: case AGENTX_MSG_UNDOSET: case AGENTX_MSG_CLEANUPSET: case AGENTX_MSG_PING:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -