📄 ax_core.c
字号:
case VT_COUNTER: case VT_GAUGE: case VT_TIMETICKS: if (EBufferSeek(ebuffp, SIZEOF_AGENTX_UNSIGNED32, 1)) return(ENVOY_AX_TOO_SMALL); if (size_check == 0) { if (order) { vbp->value_u.v_number = GLUE_GB32((GLUE_CAST_PTR(bytes))); } else { vbp->value_u.v_number = GLUE_GL32((GLUE_CAST_PTR(bytes))); } } return(0); case VT_STRING: case VT_OPAQUE: return(ax_string_decode(ebuffp, order, size_check, &vbp->value_u.v_string)); case VT_OBJECT: return(ax_obj_id_decode(ebuffp, order, size_check, &vbp->value_u.v_object, &inc)); case VT_EMPTY: case VT_NOSUCHOBJ: case VT_NOSUCHINS: case VT_ENDOFMIB: return(0); case VT_IPADDRESS: if (EBufferSeek(ebuffp, SIZEOF_AGENTX_OCT_STR + 4, 1)) return(ENVOY_AX_TOO_SMALL); if (size_check == 0) MEMCPY(vbp->value_u.v_network_address, bytes + 4, 4); return(0); case VT_COUNTER64: if (EBufferSeek(ebuffp, SIZEOF_AGENTX_UNSIGNED64, 1)) return(ENVOY_AX_TOO_SMALL); if (size_check == 0) { if (order) { vbp->value_u.v_counter64.high = GLUE_GB32((GLUE_CAST_PTR(bytes))); bytes += SIZEOF_AGENTX_UNSIGNED32; vbp->value_u.v_counter64.low = GLUE_GB32((GLUE_CAST_PTR(bytes))); } else { vbp->value_u.v_counter64.low = GLUE_GL32((GLUE_CAST_PTR(bytes))); bytes += SIZEOF_AGENTX_UNSIGNED32; vbp->value_u.v_counter64.high = GLUE_GL32((GLUE_CAST_PTR(bytes))); } } return(0); }}/****************************************************************************NAME: ax_varbind_list_decodePURPOSE: decode a varbind list due to the layout of the agentx pdus we need to read through it to find out how many varbinds we will have each of the decode routines have a tag for this that will have the routine update the packet ebuffer structure but won't try to read the data from the packet (except necessary lengths).PARAMETERS: EBUFFER_T * bits8_t VBL_T *RETURNS: int ****************************************************************************/static int ax_varbind_list_decode(EBUFFER_T *ebuffp, bits8_t order, VBL_T *vblp){VB_T dummyvbp, *vbp;int num_vbs, error_ret;ALENGTH_T save_ptr;/* so first we count the var binds, by using the size check option the other decode routines will step through the space for each item but won't try to read the data or store it into the vbp, we do need a real vbp to keep the pointer stuff happy */save_ptr = EBufferUsed(ebuffp);for(num_vbs = 0; EBufferRemaining(ebuffp); num_vbs++) { error_ret = ax_varbind_decode(ebuffp, order, 1, &dummyvbp); if (error_ret) return(error_ret); }EBufferSeek(ebuffp, save_ptr, 0);/* Set up the varbind list */if (num_vbs == 0) return(0);vbp = VarBindList_Allocate(num_vbs);if (vbp == 0) return(ENVOY_AX_ALLOCATION_FAILURE);vblp->vblist = vbp;vblp->vbl_count = num_vbs;for(; num_vbs; num_vbs--, vbp++) { error_ret = ax_varbind_decode(ebuffp, order, 0, vbp); if (error_ret) return(error_ret); }return(0);}/****************************************************************************NAME: ax_search_list_decodePURPOSE: decode a seacrh list from the bufferPARAMETERS: EBUFFER_T * bits8_t VBL_T *RETURNS: int****************************************************************************/static int ax_search_list_decode(EBUFFER_T *ebuffp, bits8_t order, VBL_T *vblp){VB_T *vbp;int num_objs, error_ret;bits8_t *bytes, inc;ALENGTH_T pkt_len, bytes_read, byte_count;/* work out how many search pairs we actually have */bytes = EBufferNext(ebuffp);pkt_len = EBufferRemaining(ebuffp);for (num_objs = 0, bytes_read = 0; bytes_read < pkt_len; num_objs++, bytes_read += byte_count, bytes += byte_count) { byte_count = (GET_AGENTX_OID_N_SUBID(bytes) + 1) * 4; }/* we should have used up all of the packet and have an even number of object id items */if ((bytes_read != pkt_len) || (num_objs%2)) return(ENVOY_AX_PARSE_ERROR);num_objs = num_objs/2;/* Set up the varbind list */if (num_objs == 0) return(0);vbp = VarBindList_Allocate(num_objs);if (vbp == 0) return(ENVOY_AX_ALLOCATION_FAILURE);vblp->vblist = vbp;vblp->vbl_count = num_objs;for(; num_objs; num_objs--, vbp++) { error_ret = ax_obj_id_decode(ebuffp, order, 0, &vbp->vb_obj_id, &vbp->ax_flags); if (error_ret) return(error_ret); error_ret = ax_obj_id_decode(ebuffp, order, 0, &vbp->ax_search_end, &inc); if (error_ret) return(error_ret); }return(0);}/********************************************************************************* envoy_ax_pkt_decode - decode a string and uses it in an AgentX packet structure* SYNOPSIS** \cs* ENVOY_AX_PKT_T * envoy_ax_pkt_decode* ( * bits8_t * pkt_str, * ALENGTH_T pkt_len, * int * error_ret * )* \ce** DESCRIPTION** This routine decodes a string and uses it to create an AgentX packet * structure.** \&NOTE: New applications should use handler routines to decode strings rather * than this routine.** PARAMETERS* \is* \i <*pkt_str>* Point to a string to decode.* \i <pkt_len>* Specify the length in bytes of the string to decode.* \i <*error_ret>* Contain an error code when this routine fails* \ie** RETURNS: If successful, this routine returns a pointer to the AgentX packet. * Otherwise, it returns 0 and sets <error_ret> to one of the following values.* \is* \i 'ENVOY_AX_ALLOCATION_FAILURE'* Unable to allocate an AgentX packet.* \i 'ENVOY_AX_PARSE_ERROR'* Unable to decode the specified string.* \i 'ENVOY_AX_TOO_SMALL'* The string is either smaller than the minimum PDU size or does not match the * expected length.* \i 'ENVOY_AX_WRONG_VERSION'* Incorrect AgentX version number specified. The only supported version is * 'ENVOY_AX_VERSION_1'.* \ie** ERRNO: N/A** SEE ALSO: envoy_ax_pkt_encode()*/ENVOY_AX_PKT_T * envoy_ax_pkt_decode(bits8_t * pkt_str, ALENGTH_T pkt_len, int * error_ret){bits8_t order, *bytes, inc;bits32_t payload_length;ENVOY_AX_PKT_T *ax_pkt;EBUFFER_T ebuffp;/* hope that things work */*error_ret = 0;/* make sure the packet is at least the minimum size */if (pkt_len < SIZEOF_AGENTX_PDU) { *error_ret = ENVOY_AX_TOO_SMALL; return(0); }/* sanity check the version */if (GET_AGENTX_PDU_VERSION(pkt_str) != ENVOY_AX_VERSION_1) { *error_ret = ENVOY_AX_WRONG_VERSION; return(0); }/* assume that the following checks will work and allocate the packet structure giving us a place to put the data we read from the byte string */ax_pkt = envoy_ax_pkt_allocate();if (ax_pkt == 0) { *error_ret = ENVOY_AX_ALLOCATION_FAILURE; return(0); }ax_pkt->version = ENVOY_AX_VERSION_1;ax_pkt->type = GET_AGENTX_PDU_TYPE(pkt_str);ax_pkt->flags = GET_AGENTX_PDU_FLAGS(pkt_str);if (ax_pkt->flags & ENVOY_AX_BIT_BYTE_ORDER) { order = 1; ax_pkt->session_id = GET_AGENTX_PDU_SESSION_ID_B(pkt_str); ax_pkt->transaction_id = GET_AGENTX_PDU_TRANS_ID_B(pkt_str); ax_pkt->packet_id = GET_AGENTX_PDU_PACKET_ID_B(pkt_str); payload_length = GET_AGENTX_PDU_PAYLOAD_LEN_B(pkt_str); }else { order = 0; ax_pkt->session_id = GET_AGENTX_PDU_SESSION_ID_L(pkt_str); ax_pkt->transaction_id = GET_AGENTX_PDU_TRANS_ID_L(pkt_str); ax_pkt->packet_id = GET_AGENTX_PDU_PACKET_ID_L(pkt_str); payload_length = GET_AGENTX_PDU_PAYLOAD_LEN_L(pkt_str); }if (payload_length > (pkt_len - SIZEOF_AGENTX_PDU)) { envoy_ax_pkt_free(ax_pkt); *error_ret = ENVOY_AX_TOO_SMALL; return(0); }/* attach the buffer to an ebuffer so we can pass it around more easily */EBufferSetup(BFL_IS_STATIC, &ebuffp, pkt_str + SIZEOF_AGENTX_PDU, payload_length);/* if the context exists get it */if (ax_pkt->flags & ENVOY_AX_BIT_NDC) { *error_ret = ax_string_decode(&ebuffp, order, 0, &ax_pkt->context); if (*error_ret) { envoy_ax_pkt_free(ax_pkt); return(0); } }/* then we read the pdu sections */bytes = EBufferNext(&ebuffp);switch(ax_pkt->type) { default: *error_ret = ENVOY_AX_PARSE_ERROR; break; case ENVOY_AX_OPEN: if (EBufferSeek(&ebuffp, 4, 1)) { *error_ret = ENVOY_AX_TOO_SMALL; break; } ax_pkt->data.open_data.timeout = GET_AGENTX_OPEN_TIMEOUT(bytes); *error_ret = ax_obj_id_decode(&ebuffp, order, 0, &ax_pkt->data.open_data.sub_id, &inc); if (*error_ret) break; *error_ret = ax_string_decode(&ebuffp, order, 0, &ax_pkt->data.open_data.descr); break; case ENVOY_AX_CLOSE: if (EBufferSeek(&ebuffp, SIZEOF_AGENTX_CLOSE, 1)) { *error_ret = ENVOY_AX_TOO_SMALL; break; } ax_pkt->data.reason = GET_AGENTX_CLOSE_REASON(bytes); break; case ENVOY_AX_REGISTER: case ENVOY_AX_UNREGISTER: if (EBufferSeek(&ebuffp, 4, 1)) { *error_ret = ENVOY_AX_TOO_SMALL; break; } ax_pkt->data.reg_data.timeout = GET_AGENTX_REG_TIMEOUT(bytes); ax_pkt->data.reg_data.priority = GET_AGENTX_REG_PRIORITY(bytes); ax_pkt->data.reg_data.range = GET_AGENTX_REG_RANGE_SUBID(bytes);#if INSTALL_ENVOY_AGENTX_2257_RANGE /* if we're behaving according to RFC2257, the range subid is relative to the start of the object id so it will change if there is a prefix (we always expand the oid on decoding) so first we read the range then we go look at the prefix and, if it's non-zero add 5 to the range */ if (GET_AGENTX_OID_PREFIX(bytes+4) && ax_pkt->data.reg_data.range) ax_pkt->data.reg_data.range += 5;#endif *error_ret = ax_obj_id_decode(&ebuffp, order, 0, &ax_pkt->data.reg_data.region, &inc); if (*error_ret) break; if (ax_pkt->data.reg_data.range) { bytes = EBufferNext(&ebuffp); if (EBufferSeek(&ebuffp, 4, 1)) { *error_ret = ENVOY_AX_TOO_SMALL; break; } if (order) { ax_pkt->data.reg_data.bound = GLUE_GB32((GLUE_CAST_PTR(bytes))); } else { ax_pkt->data.reg_data.bound = GLUE_GL32((GLUE_CAST_PTR(bytes))); } } break; case ENVOY_AX_GET: case ENVOY_AX_NEXT: *error_ret = ax_search_list_decode(&ebuffp, order, &ax_pkt->data.proc_data.vbl_str); break; case ENVOY_AX_BULK: if (EBufferSeek(&ebuffp, SIZEOF_AGENTX_BULK, 1)) { *error_ret = ENVOY_AX_TOO_SMALL; break; } if (order) { ax_pkt->data.proc_data.non_reps = GET_AGENTX_BULK_NON_REP_B(bytes); ax_pkt->data.proc_data.max_reps = GET_AGENTX_BULK_MAX_REP_B(bytes); } else { ax_pkt->data.proc_data.non_reps = GET_AGENTX_BULK_NON_REP_L(bytes); ax_pkt->data.proc_data.max_reps = GET_AGENTX_BULK_MAX_REP_L(bytes); } *error_ret = ax_search_list_decode(&ebuffp, order, &ax_pkt->data.proc_data.vbl_str); break; case ENVOY_AX_RESPONSE: if (EBufferSeek(&ebuffp, SIZEOF_AGENTX_RESP, 1)) { *error_ret = ENVOY_AX_TOO_SMALL; break; } if (order) { ax_pkt->sysuptime = GET_AGENTX_RESP_SYS_UPTIME_B(bytes); ax_pkt->error_stat = GET_AGENTX_RESP_ERROR_B(bytes); ax_pkt->error_index = GET_AGENTX_RESP_INDEX_B(bytes); } else { ax_pkt->sysuptime = GET_AGENTX_RESP_SYS_UPTIME_L(bytes); ax_pkt->error_stat = GET_AGENTX_RESP_ERROR_L(bytes); ax_pkt->error_index = GET_AGENTX_RESP_INDEX_L(bytes); } *error_ret = ax_varbind_list_decode(&ebuffp, order, &ax_pkt->data.proc_data.vbl_str); break; case ENVOY_AX_TEST: case ENVOY_AX_NOTIFY: case ENVOY_AX_INDEX_ALLOCATE: case ENVOY_AX_INDEX_DEALLOCATE: /* a varbind list */ *error_ret = ax_varbind_list_decode(&ebuffp, order, &ax_pkt->data.proc_data.vbl_str); break; case ENVOY_AX_COMMIT: case ENVOY_AX_UNDO: case ENVOY_AX_CLEANUP: case ENVOY_AX_PING: /* just headers */ break; case ENVOY_AX_ADD_AC: /* a string and an oid */ *error_ret = ax_string_decode(&ebuffp, order, 0, &ax_pkt->data.open_data.descr); if (*error_ret) break; *error_ret = ax_obj_id_decode(&ebuffp, order, 0, &ax_pkt->data.open_data.sub_id, &inc); break; case ENVOY_AX_REMOVE_AC: /* an oid */ *error_ret = ax_obj_id_decode(&ebuffp, order, 0, &ax_pkt->data.open_data.sub_id, &inc); break; }if (*error_ret) { envoy_ax_pkt_free(ax_pkt); return(0); }else return(ax_pkt);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -