📄 protocol.c
字号:
DEBUGMSG(("dumpv_send", " Reason:\t%d\n", *(bufp-4) )); DEBUGINDENTLESS(); break; case AGENTX_MSG_REGISTER: case AGENTX_MSG_UNREGISTER: if ( *out_length < 4 ) return -1; *bufp = (u_char)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++; DEBUGDUMPHEADER("send", "(Un)Register Header"); DEBUGDUMPSETUP("send", bufp-4, 4); DEBUGMSG(("dumpv_send", " Timeout:\t%d\n", *(bufp-4) )); DEBUGPRINTINDENT("dumpv_send"); DEBUGMSG(("dumpv_send", " Priority:\t%d\n", *(bufp-3) )); DEBUGPRINTINDENT("dumpv_send"); DEBUGMSG(("dumpv_send", " Range SubID:\t%d\n", *(bufp-2) )); DEBUGINDENTLESS(); *out_length -= 4; vp = pdu->variables; prefix_ptr = bufp+1; /* Points to the 'prefix' field */ DEBUGDUMPHEADER("send", "(Un)Register Prefix"); bufp = agentx_build_oid( bufp, out_length, 0, vp->name, vp->name_length, pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER); DEBUGINDENTLESS(); 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 */ DEBUGDUMPHEADER("send", "(Un)Register Range"); agentx_build_int( bufp, vp->val.objid[pdu->range_subid-1], pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER); DEBUGINDENTLESS(); 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; DEBUGPRINTINDENT("dumpv_send"); DEBUGMSG(("dumpv_send", " Range SubID tweaked:\t%d\n", *(range_ptr) )); } } break; case AGENTX_MSG_GETBULK: if ( *out_length < 4 ) return -1; DEBUGDUMPHEADER("send", "GetBulk Non-Repeaters"); agentx_build_short( bufp , pdu->non_repeaters, pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER); DEBUGDUMPHEADER("send", "GetBulk Max-Repetitions"); agentx_build_short( bufp+2, pdu->max_repetitions, pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER); DEBUGINDENTLESS(); bufp += 4; *out_length -= 4; /* Fallthrough */ case AGENTX_MSG_GET: case AGENTX_MSG_GETNEXT: DEBUGDUMPHEADER("send", "Get* Variable List"); 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; } DEBUGINDENTLESS(); 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); DEBUGDUMPHEADER("send", "Response sysUpTime"); DEBUGDUMPSETUP("send", bufp, 4); DEBUGMSG(("dumpv_send", " sysUpTime:\t%d\n", pdu->time )); DEBUGINDENTLESS(); 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); DEBUGDUMPHEADER("send", "Response errors"); DEBUGDUMPSETUP("send", bufp, 4); DEBUGMSG(("dumpv_send", " errstat:\t%d\n", pdu->errstat )); DEBUGPRINTINDENT("dumpv_send"); DEBUGMSG(("dumpv_send", " errindex:\t%d\n", pdu->errindex )); DEBUGINDENTLESS(); bufp += 4; *out_length -= 4; /* Fallthrough */ case AGENTX_MSG_INDEX_ALLOCATE: case AGENTX_MSG_INDEX_DEALLOCATE: case AGENTX_MSG_NOTIFY: case AGENTX_MSG_TESTSET: DEBUGDUMPHEADER("send", "Get* Variable List"); 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; } DEBUGINDENTLESS(); break; case AGENTX_MSG_COMMITSET: case AGENTX_MSG_UNDOSET: case AGENTX_MSG_CLEANUPSET: case AGENTX_MSG_PING: /* "Empty" packet */ break; case AGENTX_MSG_ADD_AGENT_CAPS: DEBUGDUMPHEADER("send", "AgentCaps OID"); bufp = agentx_build_oid( bufp, out_length, 0, pdu->variables->name, pdu->variables->name_length, pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER); DEBUGINDENTLESS(); if ( bufp == NULL ) return -1; DEBUGDUMPHEADER("send", "AgentCaps Description"); bufp = agentx_build_string( bufp, out_length, pdu->variables->val.string, pdu->variables->val_len, pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER); DEBUGINDENTLESS(); if ( bufp == NULL ) return -1; break; case AGENTX_MSG_REMOVE_AGENT_CAPS: DEBUGDUMPHEADER("send", "AgentCaps OID"); bufp = agentx_build_oid( bufp, out_length, 0, pdu->variables->name, pdu->variables->name_length, pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER); DEBUGINDENTLESS(); if ( bufp == NULL ) return -1; break; default: session->s_snmp_errno = SNMPERR_UNKNOWN_PDU; return -1; } DEBUGINDENTLESS(); /* Insert the payload length (ignoring the 20-byte header) and return the full length of the packet */ agentx_build_int( packet+16, (bufp-packet)-20, pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER); *out_length = bufp-packet; return 0;}intagentx_build(struct snmp_session *session, struct snmp_pdu *pdu, register u_char *packet, size_t *out_length){ int rc; rc = _agentx_build(session,pdu,packet,out_length); if (rc) { if (0 == session->s_snmp_errno) session->s_snmp_errno = SNMPERR_BAD_ASN1_BUILD; } return (rc);} /*********************** * * Utility functions for parsing an AgentX packet * ***********************/ intagentx_parse_int(u_char *data, u_int network_byte_order){ u_int value = 0; /* * Note - this doesn't handle 'PDP_ENDIAN' systems * If anyone needs this added, contact the coders list */ DEBUGDUMPSETUP("recv", data, 4); if ( network_byte_order ) { memmove( &value, data, 4);#ifndef WORDS_BIGENDIAN value = ntohl( value );#endif } else {#ifndef WORDS_BIGENDIAN memmove( &value, data, 4);#else /* The equivalent of the 'ntohl()' macro, except this macro is null on big-endian systems */ value += data[3]; value <<= 8; value += data[2]; value <<= 8; value += data[1]; value <<= 8; value += data[0];#endif } DEBUGMSG(("dumpv_recv", " Integer:\t%ld (0x%.2X)\n", value, value)); return value;}intagentx_parse_short(u_char *data, u_int network_byte_order){ u_short value = 0; if ( network_byte_order ) { memmove( &value, data, 2);#ifndef WORDS_BIGENDIAN value = ntohs( value );#endif } else {#ifndef WORDS_BIGENDIAN memmove( &value, data, 2);#else /* The equivalent of the 'ntohs()' macro, except this macro is null on big-endian systems */ value += data[1]; value <<= 8; value += data[0];#endif } DEBUGDUMPSETUP("recv", data, 2); DEBUGMSG(("dumpv_recv", " Short:\t%ld (0x%.2X)\n", value, value)); return value;}u_char *agentx_parse_oid( u_char *data, size_t *length, int *inc, oid *oid_buf, size_t *oid_len, u_int network_byte_order){ u_int n_subid; u_int prefix; int i; oid *oid_ptr = oid_buf; u_char *buf_ptr = data; if ( *length < 4 ) { DEBUGMSGTL(("agentx","Incomplete Object ID")); return NULL; } DEBUGDUMPHEADER("recv", "OID Header"); DEBUGDUMPSETUP("recv", data, 4); DEBUGMSG(("dumpv_recv", " # subids:\t%d (0x%.2X)\n", data[0], data[0])); DEBUGPRINTINDENT("dumpv_recv"); DEBUGMSG(("dumpv_recv", " prefix:\t%d (0x%.2X)\n", data[1], data[1])); DEBUGPRINTINDENT("dumpv_recv"); DEBUGMSG(("dumpv_recv", " inclusive:\t%d (0x%.2X)\n",data[2], data[2])); DEBUGINDENTLESS(); DEBUGDUMPHEADER("recv", "OID Segments"); n_subid = data[0]; prefix = data[1]; if ( inc ) *inc = data[2]; buf_ptr += 4; *length -= 4; if (n_subid == 0 && prefix == 0) { /* Null OID */ *oid_ptr = 0; oid_ptr++; *oid_ptr = 0; oid_ptr++; *oid_len = 2; DEBUGPRINTINDENT("dumpv_recv"); DEBUGMSG(("dumpv_recv", "OID: NULL (0.0)\n")); DEBUGINDENTLESS(); return buf_ptr; } if ( *length < 4*n_subid ) { DEBUGMSGTL(("agentx","Incomplete Object ID")); return NULL; } if ( prefix ) { *oid_ptr = 1; oid_ptr++; *oid_ptr = 3; oid_ptr++; *oid_ptr = 6; oid_ptr++; *oid_ptr = 1; oid_ptr++; *oid_ptr = prefix; oid_ptr++; } for ( i = 0 ; i < (int)n_subid ; i++ ) { oid_ptr[i] = agentx_parse_int( buf_ptr, network_byte_order ); buf_ptr += 4; *length -= 4; } *oid_len = ( prefix ? n_subid + 5 : n_subid ); DEBUGINDENTLESS(); DEBUGPRINTINDENT("dumpv_recv"); DEBUGMSG(("dumpv_recv", "OID: ")); DEBUGMSGOID(("dumpv_recv", oid_buf, *oid_len)); DEBUGMSG(("dumpv_recv", "\n")); return buf_ptr;}u_char *agentx_parse_string( u_char *data, size_t *length, u_char *string, size_t *str_len, u_int network_byte_order){ u_int len; if ( *length < 4 ) { DEBUGMSGTL(("agentx","Incomplete string (too short: %d)", *length)); return NULL; } len = agentx_parse_int( data, network_byte_order ); if ( *length < len + 4 ) { DEBUGMSGTL(("agentx","Incomplete string (still too short: %d)", *length)); return NULL; } if ( len > *str_len ) { DEBUGMSGTL(("agentx","String too long (too long)")); return NULL; } memmove( string, data+4, len ); string[len] = '\0'; *str_len = len; len += 3; /* Extend the string length to include the padding */ len >>= 2; len <<= 2; *length -= ( len+4 ); DEBUGDUMPSETUP("recv", data, (len+4)); DEBUGIF("dumpv_recv") { char *buf = (char *)malloc(1+len+4); sprint_asciistring(buf, string, len+4); DEBUGMSG(("dumpv_recv", "String: %s\n", buf)); free (buf); } return data + ( len+4 );}u_char*agentx_parse_opaque(u_char *data, size_t *length, int *type, u_char *opaque_buf, size_t *opaque_len, u_int network_byte_order){ union { float floatVal; double doubleVal; int intVal[2]; char c[sizeof(double)]; } fu; int tmp; u_char *buf; u_char *cp; cp = agentx_parse_string( data, length, opaque_buf, opaque_len, network_byte_order); if ( cp == NULL ) return NULL; buf = opaque_buf;#ifdef OPAQUE_SPECIAL_TYPES if (( buf[0] != ASN_OPAQUE_TAG1 ) || ( *opaque_len <= 3 )) return cp; /* Unrecognised opaque type */ switch ( buf[1] ) { case ASN_OPAQUE_FLOAT: if (( *opaque_len != (3+sizeof(float))) || ( buf[2] != sizeof(float))) return cp; /* Encoding isn't right for FLOAT */ memcpy( &fu.c[0], &buf[3], sizeof( float )); fu.intVal[0] = ntohl( fu.intVal[0] ); *opaque_len = sizeof( float ); memcpy( opaque_buf, &fu.c[0], sizeof( float )); *type = ASN_OPAQUE_FLOAT; DEBUGMSG(("dumpv_recv", "Float: %f\n", fu.floatVal)); return cp; case ASN_OPAQUE_DOUBLE: if (( *opaque_len != (3+sizeof(double))) || ( buf[2] != sizeof(double))) return cp; /* Encoding isn't right for DOUBLE */ memcpy( &fu.c[0], &buf[3], sizeof( double )); tmp = ntohl( fu.intVal[1] ); fu.intVal[1] = ntohl( fu.intVal[0] ); fu.intVal[0] = tmp; *opaque_len = sizeof( double ); memcpy( opaque_buf, &fu.c[0], sizeof( double )); *type = ASN_OPAQUE_DOUBLE; DEBUGMSG(("dumpv_recv", "Double: %lf\n", fu.doubleVal)); return cp; case ASN_OPAQUE_I64: case ASN_OPAQUE_U64: case ASN_OPAQUE_COUNTER64: default: return cp; /* Unrecognised opaque sub-type */ }#else return cp;#endif}u_char *agentx_parse_varbind( u_char *data, size_t *length, int *type, oid *oid_buf, size_t *oid_len, u_char *data_buf, size_t *data_len, u_int network_byte_order){ u_char *bufp = data; u_int int_val; struct counter64 *c64 = (struct counter64 *)data_buf; DEBUGDUMPHEADER("recv", "VarBind:"); DEBUGDUMPHEADER("recv", "Byte Order"); *type = agentx_parse_short( bufp, network_byte_order ); DEBUGINDENTLESS(); bufp += 4; *length -= 4; bufp = agentx_parse_oid( bufp, length, NULL, oid_buf, oid_len, network_byte_order ); if ( bufp == NULL ) { DEBUGINDENTLESS(); return NULL; } switch ( *type ) { case ASN_INTEGER: case ASN_COUNTER: case ASN_GAUGE: case ASN_TIMETICKS: int_val = agentx_parse_int( bufp, network_byte_order ); memmove( data_buf, &int_val, 4); *data_len = 4; bufp += 4; *length -= 4; break; case ASN_OCTET_STR: case ASN_IPADDRESS: bufp = agentx_parse_string( bufp, length, data_buf, data_len, network_byte_order ); break; case ASN_OPAQUE: bufp = agentx_parse_opaque( bufp, length, type, data_buf, data_len, network_byte_order ); break; case ASN_OBJECT_ID: bufp = agentx_parse_oid( bufp, length, NULL, (oid *)data_buf, data_len, network_byte_order ); *data_len *= 4; /* 'agentx_parse_oid()' returns the number of sub_ids */ break; case ASN_COUNTER64: if ( network_byte_order ) { c64->high = agentx_parse_int( bufp, network_byte_order ); c64->low = agentx_parse_int( bufp+4, network_byte_order ); } else { c64->low = agentx_parse_int( bufp, network_byte_order ); c64->high = agentx_parse_int( bufp+4, network_byte_order ); } *data_len = 8; bufp += 8; *length -= 8; break; case ASN_NULL: case SNMP_NOSUCHOBJECT: case SNMP_NOSUCHINSTANCE: case SNMP_ENDOFMIBVIEW: /* No data associated with these types */ *data_len = 0; break; default: DEBUGINDENTLESS(); return NULL; } DEBUGINDENTLESS(); return bufp;}/* * AgentX header: * * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | h.version | h.type | h.flags | <reserved> | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -