/* then we have the value's header */
offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag);
- value_offset = offset = get_ber_length(tvb, offset, &value_len, &ind);
+ value_offset = get_ber_length(tvb, offset, &value_len, &ind);
if (! (!pc) ) {
proto_item* pi = proto_tree_add_text(tree, tvb, seq_offset, seq_len,"the value must be in primitive encoding");
pt_varbind = proto_item_add_subtree(pi_varbind,ett_varbind);
*label = '\0';
- pi_name = proto_tree_add_item(pt_varbind,hf_snmp_objectname,tvb,name_offset,name_len,FALSE);
+ pi_name = proto_tree_add_item(pt_varbind,hf_snmp_objectname,tvb,name_offset,name_len,ENC_NA);
pt_name = proto_item_add_subtree(pi_name,ett_name);
/* fetch ObjectName and its relative oid_info */
}
}
- pi = proto_tree_add_item(pt_varbind,hfid,tvb,value_offset,value_len,FALSE);
+ pi = proto_tree_add_item(pt_varbind,hfid,tvb,value_offset,value_len,ENC_BIG_ENDIAN);
expert_add_info_format(actx->pinfo, pi, PI_RESPONSE_CODE, PI_NOTE, "%s",note);
g_strlcpy (label, note, ITEM_LABEL_LENGTH);
goto set_label;
} else if (oid_left == 0) {
if (ber_class == BER_CLASS_UNI && tag == BER_UNI_TAG_NULL) {
/* unSpecified does not require an instance sub-id add the new value and get off the way! */
- pi_value = proto_tree_add_item(pt_varbind,hf_snmp_unSpecified,tvb,value_offset,value_len,FALSE);
+ pi_value = proto_tree_add_item(pt_varbind,hf_snmp_unSpecified,tvb,value_offset,value_len,ENC_NA);
goto set_label;
} else {
proto_item* pi = proto_tree_add_text(pt_name,tvb,0,0,"A scalar should have one instance sub-id this one has none");
if ( key_len == 0 && ber_class == BER_CLASS_UNI && tag == BER_UNI_TAG_NULL) {
/* unSpecified does not require an instance sub-id add the new value and get off the way! */
- pi_value = proto_tree_add_item(pt_varbind,hf_snmp_unSpecified,tvb,value_offset,value_len,FALSE);
+ pi_value = proto_tree_add_item(pt_varbind,hf_snmp_unSpecified,tvb,value_offset,value_len,ENC_NA);
goto set_label;
}
if (IS_FT_INT(k->ft_type)) {
proto_tree_add_int(pt_name,k->hfid,tvb,name_offset,name_len,(guint)subids[key_start]);
} else { /* if it's not an unsigned int let proto_tree_add_uint throw a warning */
- proto_tree_add_uint(pt_name,k->hfid,tvb,name_offset,name_len,(guint)subids[key_start]);
+ proto_tree_add_uint64(pt_name,k->hfid,tvb,name_offset,name_len,(guint)subids[key_start]);
}
key_start++;
key_len--;
case OID_KEY_TYPE_IPADDR: {
guint32* ipv4_p = (void*)buf;
proto_tree_add_ipv4(pt_name,k->hfid,tvb,name_offset,buf_len, *ipv4_p);
+ }
break;
default:
DISSECTOR_ASSERT_NOT_REACHED();
break;
- }
}
key_start += buf_len;
if (oid_info_is_ok && oid_info->value_type) {
if (ber_class == BER_CLASS_UNI && tag == BER_UNI_TAG_NULL) {
- pi_value = proto_tree_add_item(pt_varbind,hf_snmp_unSpecified,tvb,value_offset,value_len,FALSE);
- } else {
+ pi_value = proto_tree_add_item(pt_varbind,hf_snmp_unSpecified,tvb,value_offset,value_len,ENC_NA);
+ } else {
+ /* Provide a tree_item to attach errors to, if needed. */
+ pi_value = pi_name;
+
if ((oid_info->value_type->ber_class != BER_CLASS_ANY) &&
(ber_class != oid_info->value_type->ber_class))
format_error = BER_WRONG_TAG;
-
- if ((oid_info->value_type->ber_tag != BER_TAG_ANY) &&
+ else if ((oid_info->value_type->ber_tag != BER_TAG_ANY) &&
(tag != oid_info->value_type->ber_tag))
format_error = BER_WRONG_TAG;
+ else {
+ max_len = oid_info->value_type->max_len == -1 ? 0xffffff : oid_info->value_type->max_len;
+ min_len = oid_info->value_type->min_len;
- 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) {
- format_error = BER_WRONG_LENGTH;
- } else {
- pi_value = proto_tree_add_item(pt_varbind,oid_info->value_hfid,tvb,value_offset,value_len,FALSE);
+ if ((int)value_len < min_len || (int)value_len > max_len)
+ format_error = BER_WRONG_LENGTH;
}
+
+ if (format_error == BER_NO_ERROR)
+ pi_value = proto_tree_add_item(pt_varbind,oid_info->value_hfid,tvb,value_offset,value_len,ENC_BIG_ENDIAN);
}
} else {
switch(ber_class|(tag<<4)) {
case BER_CLASS_UNI|(BER_UNI_TAG_INTEGER<<4):
{
gint64 val=0;
- unsigned offset = value_offset;
+ unsigned int_val_offset = value_offset;
unsigned i;
max_len = 5; min_len = 1;
if(value_len > 0) {
/* extend sign bit */
- if(tvb_get_guint8(tvb, offset)&0x80) {
+ if(tvb_get_guint8(tvb, int_val_offset)&0x80) {
val=-1;
}
for(i=0;i<value_len;i++) {
- val=(val<<8)|tvb_get_guint8(tvb, offset);
- offset++;
+ val=(val<<8)|tvb_get_guint8(tvb, int_val_offset);
+ int_val_offset++;
}
}
proto_tree_add_int64(pt_varbind, hf_snmp_integer32_value, tvb,value_offset,value_len, val);
break;
}
- pi_value = proto_tree_add_item(pt_varbind,hfid,tvb,value_offset,value_len,FALSE);
+ pi_value = proto_tree_add_item(pt_varbind,hfid,tvb,value_offset,value_len,ENC_BIG_ENDIAN);
if (format_error != BER_NO_ERROR) {
expert_add_info_format(actx->pinfo, pi_value, PI_UNDECODED, PI_NOTE, "Unresolved value, Missing MIB");
}
/* first bit: engine id conformance */
if (len_remain<4) return offset;
conformance = ((tvb_get_guint8(tvb, offset)>>7) & 0x01);
- proto_tree_add_item(tree, hf_snmp_engineid_conform, tvb, offset, 1, FALSE);
+ proto_tree_add_item(tree, hf_snmp_engineid_conform, tvb, offset, 1, ENC_BIG_ENDIAN);
/* 4-byte enterprise number/name */
if (len_remain<4) return offset;
case SNMP_ENGINEID_FORMAT_IPV4:
/* 4-byte IPv4 address */
if (len_remain==4) {
- proto_tree_add_item(tree, hf_snmp_engineid_ipv4, tvb, offset, 4, FALSE);
+ proto_tree_add_item(tree, hf_snmp_engineid_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
offset+=4;
len_remain=0;
}
case SNMP_ENGINEID_FORMAT_IPV6:
/* 16-byte IPv6 address */
if (len_remain==16) {
- proto_tree_add_item(tree, hf_snmp_engineid_ipv6, tvb, offset, 16, FALSE);
+ proto_tree_add_item(tree, hf_snmp_engineid_ipv6, tvb, offset, 16, ENC_NA);
offset+=16;
len_remain=0;
}
case SNMP_ENGINEID_FORMAT_MACADDRESS:
/* See: https://supportforums.cisco.com/message/3010617#3010617 for details. */
if ((enterpriseid==9)&&(len_remain==7)) {
- proto_tree_add_item(tree, hf_snmp_engineid_cisco_type, tvb, offset, 1, FALSE);
+ proto_tree_add_item(tree, hf_snmp_engineid_cisco_type, tvb, offset, 1, ENC_BIG_ENDIAN);
offset++;
len_remain--;
}
/* 6-byte MAC address */
if (len_remain==6) {
- proto_tree_add_item(tree, hf_snmp_engineid_mac, tvb, offset, 6, FALSE);
+ proto_tree_add_item(tree, hf_snmp_engineid_mac, tvb, offset, 6, ENC_BIG_ENDIAN);
offset+=6;
len_remain=0;
}
case SNMP_ENGINEID_FORMAT_TEXT:
/* max. 27-byte string, administratively assigned */
if (len_remain<=27) {
- proto_tree_add_item(tree, hf_snmp_engineid_text, tvb, offset, len_remain, FALSE);
+ proto_tree_add_item(tree, hf_snmp_engineid_text, tvb, offset, len_remain, ENC_ASCII|ENC_NA);
offset+=len_remain;
len_remain=0;
}
proto_item_append_text(item, (enterpriseid==2021) ? ": UCD-SNMP Random" : ": Net-SNMP Random");
/* demystify: 4B random, 4B epoch seconds */
if (len_remain==8) {
- proto_tree_add_item(tree, hf_snmp_engineid_data, tvb, offset, 4, FALSE);
+ proto_tree_add_item(tree, hf_snmp_engineid_data, tvb, offset, 4, ENC_NA);
seconds = tvb_get_letohl(tvb, offset+4);
ts.secs = seconds;
ts.nsecs = 0;
default:
/* max. 27 bytes, administratively assigned or unknown format */
if (len_remain<=27) {
- proto_tree_add_item(tree, hf_snmp_engineid_data, tvb, offset, len_remain, FALSE);
+ proto_tree_add_item(tree, hf_snmp_engineid_data, tvb, offset, len_remain, ENC_NA);
offset+=len_remain;
len_remain=0;
}
if (! ( user_tvb && engine_tvb ) ) return NULL;
- given_username_len = tvb_length_remaining(user_tvb,0);
+ given_username_len = tvb_ensure_length_remaining(user_tvb,0);
given_username = ep_tvb_memdup(user_tvb,0,-1);
- given_engine_len = tvb_length_remaining(engine_tvb,0);
+ given_engine_len = tvb_ensure_length_remaining(engine_tvb,0);
given_engine = ep_tvb_memdup(engine_tvb,0,-1);
for (a = localized_ues; a; a = a->next) {
* BER).
*/
if (length_remaining < 6) {
+ /*
+ * Yes. Tell the TCP dissector where the data
+ * for this message starts in the data it handed
+ * us and that we need "some more data." Don't tell
+ * it exactly how many bytes we need because if/when
+ * we ask for even more (after the header) that will
+ * break reassembly.
+ */
pinfo->desegment_offset = offset;
- pinfo->desegment_len = 6 - length_remaining;
+ pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
/*
* Return 0, which means "I didn't dissect anything
if (tree) {
item = proto_tree_add_item(tree, proto, tvb, start_offset,
- message_length, FALSE);
+ message_length, ENC_BIG_ENDIAN);
snmp_tree = proto_item_add_subtree(item, ett);
}
}
}
/* then comes an INTEGER (version)*/
- offset = get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag);
+ get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag);
if((tmp_class!=BER_CLASS_UNI)||(tmp_tag!=BER_UNI_TAG_INTEGER)) {
return 0;
}
col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMUX");
if (tree) {
- item = proto_tree_add_item(tree, proto_smux, tvb, 0, -1, FALSE);
+ item = proto_tree_add_item(tree, proto_smux, tvb, 0, -1, ENC_BIG_ENDIAN);
smux_tree = proto_item_add_subtree(item, ett_smux);
}
- dissect_SMUX_PDUs_PDU(tvb, pinfo, tree);
+ dissect_SMUX_PDUs_PDU(tvb, pinfo, smux_tree);
}
/*****************************************************/
/* Now localize the key with the engineID and pass */
/* through MD5 to produce final key */
- /* May want to ensure that engineLength <= 32, */
- /* otherwise need to use a buffer larger than 64 */
+ /* We ignore invalid engineLengths here. More strict */
+ /* checking is done in snmp_users_update_cb. */
/*****************************************************/
md5_init(&MD);
guint8 *key)
{
sha1_context SH;
- guint8 *cp, password_buf[72];
+ guint8 *cp, password_buf[64];
guint32 password_index = 0;
guint32 count = 0, i;
/*****************************************************/
/* Now localize the key with the engineID and pass */
/* through SHA to produce final key */
- /* May want to ensure that engineLength <= 32, */
- /* otherwise need to use a buffer larger than 72 */
+ /* We ignore invalid engineLengths here. More strict */
+ /* checking is done in snmp_users_update_cb. */
/*****************************************************/
- memcpy(password_buf, key, 20);
- memcpy(password_buf+20, engineID, engineLength);
- memcpy(password_buf+20+engineLength, key, 20);
sha1_starts(&SH);
- sha1_update(&SH, password_buf, 40+engineLength);
+ sha1_update(&SH, key, 20);
+ sha1_update(&SH, engineID, engineLength);
+ sha1_update(&SH, key, 20);
sha1_finish(&SH, key);
return;
}
for (i=0; i<num_ueas-1; i++) {
snmp_ue_assoc_t* u = &(ueas[i]);
+ /* RFC 3411 section 5 */
+ if ((u->engine.len > 0) && (u->engine.len < 5 || u->engine.len > 32)) {
+ g_string_append_printf(es, "Invalid engineId length (%u). Must be between 5 and 32 (10 and 64 hex digits)\n", u->engine.len);
+ }
+
if ( u->user.userName.len == ue->user.userName.len
&& u->engine.len == ue->engine.len ) {
if (u->engine.len > 0 && memcmp( u->engine.data, ue->engine.data, u->engine.len ) == 0) {
if ( memcmp( u->user.userName.data, ue->user.userName.data, ue->user.userName.len ) == 0 ) {
/* XXX: make a string for the engineId */
- g_string_append_printf(es,"duplicate key (userName='%s')\n",ue->user.userName.data);
+ g_string_append_printf(es,"Duplicate key (userName='%s')\n",ue->user.userName.data);
}
}
if (u->engine.len == 0) {
if ( memcmp( u->user.userName.data, ue->user.userName.data, ue->user.userName.len ) == 0 ) {
- g_string_append_printf(es,"duplicate key (userName='%s' engineId=NONE)\n",ue->user.userName.data);
+ g_string_append_printf(es,"Duplicate key (userName='%s' engineId=NONE)\n",ue->user.userName.data);
}
}
}
}
if (es->len) {
- g_string_truncate(es,es->len-2);
+ g_string_truncate(es,es->len-1);
*err = ep_strdup(es->str);
}