diff options
author | Luis Ontanon <luis.ontanon@gmail.com> | 2007-09-13 16:49:51 +0000 |
---|---|---|
committer | Luis Ontanon <luis.ontanon@gmail.com> | 2007-09-13 16:49:51 +0000 |
commit | fb34ef1f2c03170d96ca9dda0ec192a4e5051e9e (patch) | |
tree | eb8ff9f94e4dec0d27beee0fb278a69d2cd3f553 /epan | |
parent | 652df63c5fe04f1cb6715206523dd29f65ddb3f7 (diff) |
Given the opportunity I check in the changes to snmp I got in this machine.
- Indexing (implied and not) is OK now, however indexes for related tables (AUGMENT, EXTEND, etc) are registered many times.
svn path=/trunk/; revision=22861
Diffstat (limited to 'epan')
-rw-r--r-- | epan/dissectors/packet-cops.c | 6 | ||||
-rw-r--r-- | epan/dissectors/packet-snmp.c | 143 | ||||
-rw-r--r-- | epan/oids.c | 32 | ||||
-rw-r--r-- | epan/oids.h | 9 |
4 files changed, 111 insertions, 79 deletions
diff --git a/epan/dissectors/packet-cops.c b/epan/dissectors/packet-cops.c index 420a094443..421cb8e1e8 100644 --- a/epan/dissectors/packet-cops.c +++ b/epan/dissectors/packet-cops.c @@ -1470,9 +1470,9 @@ static int dissect_cops_pr_object_data(tvbuff_t *tvb, packet_info *pinfo, guint3 /* * XXX: LAZYNESS WARNING: - * We are assuming that for of the first element in the sequence - * that describes an entry subid==1 and the subsequent elements - * use ++subid; this is true for all IETF's PIBs (and good sense + * We are assuming that for the first element in the sequence + * that describes an entry subid==1, and, that the subsequent elements + * use ++subid; This is true for all IETF's PIBs (and good sense * indicates it should be this way) but AFAIK there's nothing in * SMIv2 that imposes this restriction. -- a lazy lego */ diff --git a/epan/dissectors/packet-snmp.c b/epan/dissectors/packet-snmp.c index 579a9e986c..3ae1ed13d4 100644 --- a/epan/dissectors/packet-snmp.c +++ b/epan/dissectors/packet-snmp.c @@ -493,6 +493,8 @@ extern int dissect_snmp_VarBind(gboolean implicit_tag _U_, int min_len = 0, max_len = 0; gboolean oid_info_is_ok; const char* oid_string = NULL; + enum { NO_ERROR, WRONG_LENGTH, WRONG_TAG} format_error = NO_ERROR; + seq_offset = offset; /* first have the VarBind's sequence header */ @@ -567,8 +569,10 @@ extern int dissect_snmp_VarBind(gboolean implicit_tag _U_, proto_item* pi; const char* note; - if (value_len != 0) - goto expected_other_size; + if (value_len != 0) { + min_len = max_len = 0; + format_error = WRONG_LENGTH; + } switch (tag) { case SERR_NSO: @@ -587,7 +591,7 @@ extern int dissect_snmp_VarBind(gboolean implicit_tag _U_, pi = proto_tree_add_text(pt_varbind,tvb,0,0,"Wrong tag for Error Value: expected 0, 1, or 2 but got: %d",tag); pt = proto_item_add_subtree(pi,ett_decoding_error); expert_add_info_format(actx->pinfo, pi, PI_MALFORMED, PI_WARN, "Wrong tag for SNMP VarBind error value"); - return dissect_unknown_ber(actx->pinfo, tvb, value_start, tree); + return dissect_unknown_ber(actx->pinfo, tvb, value_start, pt); } } @@ -647,6 +651,8 @@ extern int dissect_snmp_VarBind(gboolean implicit_tag _U_, if (k) { for (;k;k = k->next) { + guint suboid_len; + if (key_start >= oid_matched+oid_left) { proto_item* pi = proto_tree_add_text(pt_name,tvb,0,0,"index sub-oid shorter than expected"); expert_add_info_format(actx->pinfo, pi, PI_MALFORMED, PI_WARN, "index sub-oid shorter than expected"); @@ -654,7 +660,7 @@ extern int dissect_snmp_VarBind(gboolean implicit_tag _U_, goto indexing_done; } - switch(k->key_type) { + switch(k->key_type) { case OID_KEY_TYPE_WRONG: { proto_item* pi = proto_tree_add_text(pt_name,tvb,0,0,"OID instaces not handled, if you want this implemented please contact the wireshark developpers"); expert_add_info_format(actx->pinfo, pi, PI_UNDECODED, PI_WARN, "Unimplemented instance index"); @@ -667,12 +673,22 @@ extern int dissect_snmp_VarBind(gboolean implicit_tag _U_, key_len--; continue; /* k->next */ } + case OID_KEY_TYPE_IMPLIED_OID: + suboid_len = key_len; + + goto show_oid_index; + case OID_KEY_TYPE_OID: { - guint suboid_len = subids[key_start++]; - guint32* suboid = &(subids[key_start]); guint8* suboid_buf; guint suboid_buf_len; + guint32* suboid; + + suboid_len = subids[key_start++]; + key_len--; +show_oid_index: + suboid = &(subids[key_start]); + if( suboid_len == 0 ) { proto_item* pi = proto_tree_add_text(pt_name,tvb,0,0,"an index sub-oid OID cannot be 0 bytes long!"); expert_add_info_format(actx->pinfo, pi, PI_MALFORMED, PI_WARN, "index sub-oid OID with len=0"); @@ -680,7 +696,7 @@ extern int dissect_snmp_VarBind(gboolean implicit_tag _U_, goto indexing_done; } - if( key_len-1 < suboid_len ) { + if( key_len < suboid_len ) { proto_item* pi = proto_tree_add_text(pt_name,tvb,0,0,"index sub-oid should not be longer than remaining oid size"); expert_add_info_format(actx->pinfo, pi, PI_MALFORMED, PI_WARN, "index sub-oid longer than remaining oid size"); oid_info_is_ok = FALSE; @@ -699,20 +715,36 @@ extern int dissect_snmp_VarBind(gboolean implicit_tag _U_, } default: { guint8* buf; - guint buf_len = k->num_subids; - guint32* suboid = &(subids[key_start]); + guint buf_len; + guint32* suboid; guint i; - if(!buf_len) { - buf_len = *suboid; - suboid++; - key_start++; - key_len--; - } + + switch (k->key_type) { + case OID_KEY_TYPE_IPADDR: + suboid = &(subids[key_start]); + buf_len = 4; + break; + case OID_KEY_TYPE_IMPLIED_STRING: + case OID_KEY_TYPE_IMPLIED_BYTES: + suboid = &(subids[key_start]); + buf_len = key_len; + break; + default: + buf_len = k->num_subids; + suboid = &(subids[key_start]); + + if(!buf_len) { + buf_len = *suboid++; + key_len--; + key_start++; + } + break; + } if( key_len < buf_len ) { - proto_item* pi = proto_tree_add_text(pt_name,tvb,0,0,"index sub-oid should not be longer than remaining oid size"); - expert_add_info_format(actx->pinfo, pi, PI_MALFORMED, PI_WARN, "index sub-oid longer than remaining oid size"); + proto_item* pi = proto_tree_add_text(pt_name,tvb,0,0,"index string should not be longer than remaining oid size"); + expert_add_info_format(actx->pinfo, pi, PI_MALFORMED, PI_WARN, "index string longer than remaining oid size"); oid_info_is_ok = FALSE; goto indexing_done; } @@ -724,12 +756,12 @@ extern int dissect_snmp_VarBind(gboolean implicit_tag _U_, switch(k->key_type) { case OID_KEY_TYPE_STRING: - case OID_KEY_TYPE_FIXED_STRING: + case OID_KEY_TYPE_IMPLIED_STRING: proto_tree_add_string(pt_name,k->hfid,tvb,name_offset,buf_len, buf); break; case OID_KEY_TYPE_BYTES: case OID_KEY_TYPE_NSAP: - case OID_KEY_TYPE_FIXED_BYTES: + case OID_KEY_TYPE_IMPLIED_BYTES: proto_tree_add_bytes(pt_name,k->hfid,tvb,name_offset,buf_len, buf); break; case OID_KEY_TYPE_IPADDR: { @@ -750,7 +782,7 @@ extern int dissect_snmp_VarBind(gboolean implicit_tag _U_, } goto indexing_done; } else { - proto_item* pi = proto_tree_add_text(pt_name,tvb,0,0,"we do not know how to handle this OID, if you want this implemented please contact the wireshark developers"); + proto_item* pi = proto_tree_add_text(pt_name,tvb,0,0,"We do not know how to handle this OID, if you want this implemented please contact the wireshark developers"); expert_add_info_format(actx->pinfo, pi, PI_UNDECODED, PI_WARN, "Unimplemented instance index"); oid_info_is_ok = FALSE; goto indexing_done; @@ -776,18 +808,17 @@ indexing_done: } else { if ((oid_info->value_type->ber_class != BER_CLASS_ANY) && (ber_class != oid_info->value_type->ber_class)) - goto expected_different; + format_error = WRONG_TAG; if ((oid_info->value_type->ber_tag != BER_TAG_ANY) && (tag != oid_info->value_type->ber_tag)) - goto expected_different; + format_error = WRONG_TAG; max_len = oid_info->value_type->max_len == -1 ? 0xffffff : oid_info->value_type->max_len; min_len = oid_info->value_type->min_len; if ((int)value_len < min_len || (int)value_len > max_len) - goto expected_other_size; - + format_error = WRONG_LENGTH; pi_value = proto_tree_add_item(pt_varbind,oid_info->value_hfid,tvb,value_offset,value_len,FALSE); } @@ -795,20 +826,20 @@ indexing_done: switch(ber_class|(tag<<4)) { case BER_CLASS_UNI|(BER_UNI_TAG_INTEGER<<4): max_len = 4; min_len = 1; - if (value_len > (guint)max_len && value_len < (guint)min_len) goto expected_other_size; + if (value_len > (guint)max_len && value_len < (guint)min_len) format_error = WRONG_LENGTH; hfid = hf_snmp_integer32_value; break; case BER_CLASS_UNI|(BER_UNI_TAG_OCTETSTRING<<4): hfid = hf_snmp_octestring_value; break; case BER_CLASS_UNI|(BER_UNI_TAG_OID<<4): - max_len = -1; min_len = 2; - if (value_len < (guint)min_len) goto expected_other_size; + max_len = -1; min_len = 1; + if (value_len < (guint)min_len) format_error = WRONG_LENGTH; hfid = hf_snmp_oid_value; break; case BER_CLASS_UNI|(BER_UNI_TAG_NULL<<4): max_len = 0; min_len = 0; - if (value_len != 0) goto expected_other_size; + if (value_len != 0) format_error = WRONG_LENGTH; hfid = hf_snmp_null_value; break; case BER_CLASS_APP: /* | (SNMP_IPA<<4)*/ @@ -880,30 +911,34 @@ set_label: valstr = valstr ? valstr+2 : label; proto_item_set_text(pi_varbind,"%s: %s",repr,valstr); - - return seq_offset + seq_len; - -expected_other_size: { - proto_item* pi = proto_tree_add_text(tree,tvb,0,0,"Wrong value length: %u expecting: %u <= len <= %u", - value_len, - min_len, - max_len == -1 ? 0xFFFFFF : max_len); - pt = proto_item_add_subtree(pi,ett_decoding_error); - expert_add_info_format(actx->pinfo, pi, PI_MALFORMED, PI_WARN, "Wrong length for SNMP VarBind/value"); - return dissect_unknown_ber(actx->pinfo, tvb, value_start, pt); - } - -expected_different: { - proto_item* pi = proto_tree_add_text(tree,tvb,0,0,"Wrong class/tag for Value expected: %d,%d got: %d,%d", - oid_info->value_type->ber_class, - oid_info->value_type->ber_tag, - ber_class, - tag); - pt = proto_item_add_subtree(pi,ett_decoding_error); - expert_add_info_format(actx->pinfo, pi, PI_MALFORMED, PI_WARN, "Wrong class/tag for SNMP VarBind/value"); - return dissect_unknown_ber(actx->pinfo, tvb, value_start, tree); + + switch (format_error) { + case WRONG_LENGTH: { + proto_tree* pt = proto_item_add_subtree(pi_value,ett_decoding_error); + proto_item* pi = proto_tree_add_text(pt,tvb,0,0,"Wrong value length: %u expecting: %u <= len <= %u", + value_len, + min_len, + max_len == -1 ? 0xFFFFFF : max_len); + pt = proto_item_add_subtree(pi,ett_decoding_error); + expert_add_info_format(actx->pinfo, pi, PI_MALFORMED, PI_WARN, "Wrong length for SNMP VarBind/value"); + return dissect_unknown_ber(actx->pinfo, tvb, value_start, pt); + } + case WRONG_TAG: { + proto_tree* pt = proto_item_add_subtree(pi_value,ett_decoding_error); + proto_item* pi = proto_tree_add_text(pt,tvb,0,0,"Wrong class/tag for Value expected: %d,%d got: %d,%d", + oid_info->value_type->ber_class, + oid_info->value_type->ber_tag, + ber_class, + tag); + pt = proto_item_add_subtree(pi,ett_decoding_error); + expert_add_info_format(actx->pinfo, pi, PI_MALFORMED, PI_WARN, "Wrong class/tag for SNMP VarBind/value"); + return dissect_unknown_ber(actx->pinfo, tvb, value_start, pt); + } + default: + break; } - + + return seq_offset + seq_len; } @@ -2816,7 +2851,7 @@ static void dissect_SMUX_PDUs_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, pro /*--- End of included file: packet-snmp-fn.c ---*/ -#line 1364 "packet-snmp-template.c" +#line 1399 "packet-snmp-template.c" guint @@ -3592,7 +3627,7 @@ void proto_register_snmp(void) { "snmp.T_operation", HFILL }}, /*--- End of included file: packet-snmp-hfarr.c ---*/ -#line 1875 "packet-snmp-template.c" +#line 1910 "packet-snmp-template.c" }; /* List of subtrees */ @@ -3632,7 +3667,7 @@ void proto_register_snmp(void) { &ett_snmp_RReqPDU, /*--- End of included file: packet-snmp-ettarr.c ---*/ -#line 1891 "packet-snmp-template.c" +#line 1926 "packet-snmp-template.c" }; module_t *snmp_module; static uat_field_t users_fields[] = { diff --git a/epan/oids.c b/epan/oids.c index dcbe3d3be0..312791a7e9 100644 --- a/epan/oids.c +++ b/epan/oids.c @@ -60,8 +60,8 @@ static const oid_value_type_t counter32_type = { FT_UINT32, BASE_DEC, BER_CLAS static const oid_value_type_t unsigned32_type = { FT_UINT32, BASE_DEC, BER_CLASS_APP, 2, 1, 4, OID_KEY_TYPE_INTEGER, 1}; static const oid_value_type_t timeticks_type = { FT_UINT32, BASE_DEC, BER_CLASS_APP, 3, 1, 4, OID_KEY_TYPE_INTEGER, 1}; static const oid_value_type_t opaque_type = { FT_BYTES, BASE_NONE, BER_CLASS_APP, 4, 1, 4, OID_KEY_TYPE_BYTES, 0}; -static const oid_value_type_t nsap_type = { FT_BYTES, BASE_NONE, BER_CLASS_APP, 5, 8, 8, OID_KEY_TYPE_NSAP, 0}; -static const oid_value_type_t counter64_type = { FT_UINT64, BASE_NONE, BER_CLASS_APP, 6, 8, 8, OID_KEY_TYPE_INTEGER, 1}; +static const oid_value_type_t nsap_type = { FT_BYTES, BASE_NONE, BER_CLASS_APP, 5, 0, -1, OID_KEY_TYPE_NSAP, 0}; +static const oid_value_type_t counter64_type = { FT_UINT64, BASE_DEC, BER_CLASS_APP, 6, 1, 8, OID_KEY_TYPE_INTEGER, 1}; static const oid_value_type_t ipv6_type = { FT_IPv6, BASE_NONE, BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, 16, 16, OID_KEY_TYPE_BYTES, 16}; static const oid_value_type_t float_type = { FT_FLOAT, BASE_DEC, BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, 4, 4, OID_KEY_TYPE_WRONG, 0}; static const oid_value_type_t double_type = { FT_DOUBLE, BASE_DEC, BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, 8, 8, OID_KEY_TYPE_WRONG, 0}; @@ -344,6 +344,7 @@ static inline oid_kind_t smikind(SmiNode* sN, oid_key_t** key_p) { SmiElement* sE; oid_key_t* kl = NULL; const oid_value_type_t* typedata = NULL; + gboolean implied; switch (sN->indexkind) { case SMI_INDEX_INDEX: @@ -351,12 +352,14 @@ static inline oid_kind_t smikind(SmiNode* sN, oid_key_t** key_p) { case SMI_INDEX_AUGMENT: case SMI_INDEX_REORDER: case SMI_INDEX_SPARSE: - case SMI_INDEX_UNKNOWN: case SMI_INDEX_EXPAND: + sN = smiGetRelatedNode(sN); + break; + case SMI_INDEX_UNKNOWN: return OID_KIND_UNKNOWN; }; - + implied = sN->implied; for (sE = smiGetFirstElement(sN); sE; sE = smiGetNextElement(sE)) { SmiNode* elNode = smiGetElementNode(sE) ; @@ -420,22 +423,15 @@ static inline oid_kind_t smikind(SmiNode* sN, oid_key_t** key_p) { kl = k; } -#if 0 - if (sN->implied) { + if (implied) { switch (kl->key_type) { - case OID_KEY_TYPE_BYTES: - if (kl->num_subids) - kl->key_type = OID_KEY_TYPE_FIXED_BYTES; - break; - case OID_KEY_TYPE_STRING: - if (kl->num_subids) - kl->key_type = OID_KEY_TYPE_FIXED_STRING; - break; - default: - break; + case OID_KEY_TYPE_BYTES: kl->key_type = OID_KEY_TYPE_IMPLIED_BYTES; break; + case OID_KEY_TYPE_STRING: kl->key_type = OID_KEY_TYPE_IMPLIED_STRING; break; + case OID_KEY_TYPE_OID: kl->key_type = OID_KEY_TYPE_IMPLIED_OID; break; + default: break; } } -#endif + return OID_KIND_ROW; } case SMI_NODEKIND_NODE: return OID_KIND_NODE; @@ -909,7 +905,7 @@ guint oid_subid2encoded(guint subids_len, guint32* subids, guint8** bytes_p) { guint8* bytes; guint8* b; - if ( !subids || *subids > 2 || subids_len < 2) { + if ( !subids || subids_len <= 0) { *bytes_p = NULL; return 0; } diff --git a/epan/oids.h b/epan/oids.h index 9e35df2321..d3823a8ca6 100644 --- a/epan/oids.h +++ b/epan/oids.h @@ -43,13 +43,14 @@ typedef struct _oid_bits_info_t { typedef enum _oid_key_type_t { OID_KEY_TYPE_WRONG, OID_KEY_TYPE_INTEGER, - OID_KEY_TYPE_FIXED_STRING, - OID_KEY_TYPE_FIXED_BYTES, + OID_KEY_TYPE_OID, OID_KEY_TYPE_STRING, OID_KEY_TYPE_BYTES, OID_KEY_TYPE_NSAP, - OID_KEY_TYPE_OID, - OID_KEY_TYPE_IPADDR + OID_KEY_TYPE_IPADDR, + OID_KEY_TYPE_IMPLIED_OID, + OID_KEY_TYPE_IMPLIED_STRING, + OID_KEY_TYPE_IMPLIED_BYTES } oid_key_type_t; typedef struct _oid_value_type_t { |