aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-3g-a11.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2005-03-02 21:08:47 +0000
committerGuy Harris <guy@alum.mit.edu>2005-03-02 21:08:47 +0000
commit439a65b82f8a64069df5cdbeac298c1a37cd15c9 (patch)
tree59a3f2811677830bf0d26e4c4b8c5f529b945f35 /epan/dissectors/packet-3g-a11.c
parent7cb9e36324c2faf2aef4c5c4a204fed5a2220ccb (diff)
Use "tvb_get_string()" to fetch strings from the packet, rather than
filling up a fixed-length buffer. Add a bunch of length checks. Clean up indentation. svn path=/trunk/; revision=13574
Diffstat (limited to 'epan/dissectors/packet-3g-a11.c')
-rw-r--r--epan/dissectors/packet-3g-a11.c394
1 files changed, 247 insertions, 147 deletions
diff --git a/epan/dissectors/packet-3g-a11.c b/epan/dissectors/packet-3g-a11.c
index c04207319e..c077a54aa9 100644
--- a/epan/dissectors/packet-3g-a11.c
+++ b/epan/dissectors/packet-3g-a11.c
@@ -313,8 +313,6 @@ static const struct radius_attribute attrs[]={
};
#define NUM_ATTR (sizeof(attrs)/sizeof(struct radius_attribute))
-#define MAX_STRVAL 16
-
#define RADIUS_VENDOR_SPECIFIC 26
#define SKIP_HDR_LEN 6
@@ -334,7 +332,7 @@ dissect_a11_radius( tvbuff_t *tvb, int offset, proto_tree *tree, int app_len)
guint offset0;
guint radius_offset;
guint i;
- guchar str_val[MAX_STRVAL];
+ guint8 *str_val;
guint radius_vendor_id = 0;
/* None of this really matters if we don't have a tree */
@@ -357,15 +355,30 @@ dissect_a11_radius( tvbuff_t *tvb, int offset, proto_tree *tree, int app_len)
{
radius_type = tvb_get_guint8(tvb, offset);
- radius_len = tvb_get_guint8(tvb, offset + 1);
+ radius_len = tvb_get_guint8(tvb, offset + 1);
+ if (radius_len < 2)
+ {
+ proto_tree_add_text(radius_tree, tvb, offset, 2,
+ "Bogus RADIUS length %lu, should be >= 2",
+ (unsigned long)radius_len);
+ break;
+ }
if (radius_type == RADIUS_VENDOR_SPECIFIC)
{
+ if (radius_len < SKIP_HDR_LEN)
+ {
+ proto_tree_add_text(radius_tree, tvb, offset, radius_len,
+ "Bogus RADIUS length %lu, should be >= %u",
+ (unsigned long)radius_len, SKIP_HDR_LEN);
+ offset += radius_len;
+ continue;
+ }
radius_vendor_id = tvb_get_ntohl(tvb, offset +2);
if(radius_vendor_id != VENDOR_THE3GPP2)
{
- ti = proto_tree_add_text(radius_tree, tvb, offset, radius_len,
+ proto_tree_add_text(radius_tree, tvb, offset, radius_len,
"Unknown Vendor-specific Attribute (Vendor Id: %x)", radius_vendor_id);
offset += radius_len;
continue;
@@ -377,25 +390,28 @@ dissect_a11_radius( tvbuff_t *tvb, int offset, proto_tree *tree, int app_len)
/**** ad-hoc ***/
if(radius_type == 31)
{
- strncpy(str_val, tvb_get_ptr(tvb,offset+2,radius_len-2),
- radius_len-2);
- if(radius_len-2 < MAX_STRVAL) {
- str_val[radius_len-2] = '\0';
- }
- else {
- str_val[MAX_STRVAL-1] = '\0';
- }
- ti = proto_tree_add_text(radius_tree, tvb, offset, radius_len,
+ str_val = tvb_get_string(tvb,offset+2,radius_len-2);
+ proto_tree_add_text(radius_tree, tvb, offset, radius_len,
"MSID: %s", str_val);
+ g_free(str_val);
}
else if (radius_type == 46)
{
- ti = proto_tree_add_text(radius_tree, tvb, offset, radius_len,
- "Acct Session Time: %d",tvb_get_ntohl(tvb,offset+2));
+ if (radius_len < 2+4)
+ {
+ proto_tree_add_text(radius_tree, tvb, offset, radius_len,
+ "Bogus RADIUS length %lu, should be >= %u",
+ (unsigned long)radius_len, 2+4);
+ }
+ else
+ {
+ proto_tree_add_text(radius_tree, tvb, offset, radius_len,
+ "Acct Session Time: %d",tvb_get_ntohl(tvb,offset+2));
+ }
}
else
{
- ti = proto_tree_add_text(radius_tree, tvb, offset, radius_len,
+ proto_tree_add_text(radius_tree, tvb, offset, radius_len,
"Unknown RADIUS Attributes (Type: %d)", radius_type);
}
@@ -403,18 +419,38 @@ dissect_a11_radius( tvbuff_t *tvb, int offset, proto_tree *tree, int app_len)
continue;
}
- radius_len = tvb_get_guint8(tvb, offset + 1);
-
offset += SKIP_HDR_LEN;
+ radius_len -= SKIP_HDR_LEN;
radius_offset = 0;
- /* Detect Airlink Record Type */
+ /* Detect Airlink Record Type */
- while (radius_len - 6 > radius_offset)
+ while (radius_len > radius_offset)
{
+ if (radius_len < radius_offset + 2)
+ {
+ proto_tree_add_text(radius_tree, tvb, offset + radius_offset, 2,
+ "Bogus RADIUS length %lu, should be >= %u",
+ (unsigned long)(radius_len + SKIP_HDR_LEN),
+ radius_offset + 2 + SKIP_HDR_LEN);
+ return;
+ }
radius_subtype = tvb_get_guint8(tvb, offset + radius_offset);
- attribute_len = tvb_get_guint8(tvb, offset + radius_offset + 1);
+ attribute_len = tvb_get_guint8(tvb, offset + radius_offset + 1);
+ if (attribute_len < 2)
+ {
+ proto_tree_add_text(radius_tree, tvb, offset + radius_offset, 2,
+ "Bogus attribute length %u, should be >= 2", attribute_len);
+ return;
+ }
+ if (attribute_len > radius_len - radius_offset)
+ {
+ proto_tree_add_text(radius_tree, tvb, offset + radius_offset, 2,
+ "Bogus attribute length %u, should be <= %lu",
+ attribute_len, (unsigned long)(radius_len - radius_offset));
+ return;
+ }
attribute_type = -1;
for(i = 0; i < NUM_ATTR; i++) {
@@ -422,56 +458,50 @@ dissect_a11_radius( tvbuff_t *tvb, int offset, proto_tree *tree, int app_len)
attribute_type = i;
break;
}
- }
+ }
if(attribute_type >= 0) {
switch(attrs[attribute_type].data_type) {
case ATTR_TYPE_INT:
- ti = proto_tree_add_text(radius_tree, tvb, offset + radius_offset,
+ proto_tree_add_text(radius_tree, tvb, offset + radius_offset,
attribute_len, "3GPP2: %s (%04x)", attrs[attribute_type].attrname,
tvb_get_ntohl(tvb,offset + radius_offset + 2));
break;
case ATTR_TYPE_IPV4:
- ti = proto_tree_add_text(radius_tree, tvb, offset + radius_offset,
+ proto_tree_add_text(radius_tree, tvb, offset + radius_offset,
attribute_len, "3GPP2: %s (%s)", attrs[attribute_type].attrname,
ip_to_str(tvb_get_ptr(tvb,offset + radius_offset + 2,4)));
break;
case ATTR_TYPE_TYPE:
- ti = proto_tree_add_text(radius_tree, tvb, offset + radius_offset,
+ proto_tree_add_text(radius_tree, tvb, offset + radius_offset,
attribute_len, "3GPP2: %s (%s)", attrs[attribute_type].attrname,
val_to_str(tvb_get_ntohl(tvb,offset+radius_offset+2),
a11_airlink_types,"Unknown"));
break;
case ATTR_TYPE_STR:
- strncpy(str_val, tvb_get_ptr(tvb,offset+radius_offset+2,attribute_len - 2),
- attribute_len - 2);
- if(attribute_len - 2 < MAX_STRVAL) {
- str_val[attribute_len - 2] = '\0';
- }
- else {
- str_val[MAX_STRVAL-1] = '\0';
- }
- ti = proto_tree_add_text(radius_tree, tvb, offset+radius_offset,
+ str_val = tvb_get_string(tvb,offset+radius_offset+2,attribute_len-2);
+ proto_tree_add_text(radius_tree, tvb, offset+radius_offset,
attribute_len,
"3GPP2: %s (%s)", attrs[attribute_type].attrname, str_val);
+ g_free(str_val);
break;
case ATTR_TYPE_NULL:
break;
default:
- ti = proto_tree_add_text(radius_tree, tvb, offset, radius_len,
+ proto_tree_add_text(radius_tree, tvb, offset+radius_offset, attribute_len,
"RADIUS: %s", attrs[attribute_type].attrname);
break;
}
}
else {
- ti = proto_tree_add_text(radius_tree, tvb, offset, radius_len,
+ proto_tree_add_text(radius_tree, tvb, offset+radius_offset, attribute_len,
"RADIUS: Unknown 3GPP2 Attribute (Type:%d, SubType:%d)",
radius_type,radius_subtype);
}
radius_offset += attribute_len;
}
- offset += radius_len - 6;
+ offset += radius_len;
}
@@ -501,140 +531,210 @@ dissect_a11_extensions( tvbuff_t *tvb, int offset, proto_tree *tree)
/* And, handle each extension */
while (tvb_reported_length_remaining(tvb, offset) > 0) {
- /* Get our extension info */
- ext_type = tvb_get_guint8(tvb, offset);
- if (ext_type == GEN_AUTH_EXT) {
- /*
- * Very nasty . . breaks normal extensions, since the length is
- * in the wrong place :(
- */
- ext_subtype = tvb_get_guint8(tvb, offset + 1);
- ext_len = tvb_get_ntohs(tvb, offset + 2);
- hdrLen = 4;
+ /* Get our extension info */
+ ext_type = tvb_get_guint8(tvb, offset);
+ if (ext_type == GEN_AUTH_EXT) {
+ /*
+ * Very nasty . . breaks normal extensions, since the length is
+ * in the wrong place :(
+ */
+ ext_subtype = tvb_get_guint8(tvb, offset + 1);
+ ext_len = tvb_get_ntohs(tvb, offset + 2);
+ hdrLen = 4;
} else if (ext_type == CVSE_EXT || ext_type == OLD_CVSE_EXT) {
- ext_len = tvb_get_ntohs(tvb, offset + 2);
- ext_subtype = tvb_get_guint8(tvb, offset + 8);
+ ext_len = tvb_get_ntohs(tvb, offset + 2);
+ ext_subtype = tvb_get_guint8(tvb, offset + 8);
hdrLen = 4;
- } else {
- ext_len = tvb_get_guint8(tvb, offset + 1);
- hdrLen = 2;
- }
-
- ti = proto_tree_add_text(exts_tree, tvb, offset, ext_len + hdrLen,
- "Extension: %s",
- val_to_str(ext_type, a11_ext_types,
- "Unknown Extension %u"));
- ext_tree = proto_item_add_subtree(ti, ett_a11_ext);
-
- proto_tree_add_item(ext_tree, hf_a11_ext_type, tvb, offset, 1, ext_type);
- offset++;
+ } else {
+ ext_len = tvb_get_guint8(tvb, offset + 1);
+ hdrLen = 2;
+ }
+
+ ti = proto_tree_add_text(exts_tree, tvb, offset, ext_len + hdrLen,
+ "Extension: %s",
+ val_to_str(ext_type, a11_ext_types,
+ "Unknown Extension %u"));
+ ext_tree = proto_item_add_subtree(ti, ett_a11_ext);
+
+ proto_tree_add_item(ext_tree, hf_a11_ext_type, tvb, offset, 1, ext_type);
+ offset++;
+
+ if (ext_type == SS_EXT) {
+ proto_tree_add_uint(ext_tree, hf_a11_ext_len, tvb, offset, 1, ext_len);
+ offset++;
+ }
+ else if(ext_type == CVSE_EXT || ext_type == OLD_CVSE_EXT) {
+ offset++;
+ proto_tree_add_uint(ext_tree, hf_a11_ext_len, tvb, offset, 2, ext_len);
+ offset+=2;
+ }
+ else if (ext_type != GEN_AUTH_EXT) {
+ /* Another nasty hack since GEN_AUTH_EXT broke everything */
+ proto_tree_add_uint(ext_tree, hf_a11_ext_len, tvb, offset, 1, ext_len);
+ offset++;
+ }
- if (ext_type == SS_EXT) {
- proto_tree_add_uint(ext_tree, hf_a11_ext_len, tvb, offset, 1, ext_len);
- offset++;
- }
- else if(ext_type == CVSE_EXT || ext_type == OLD_CVSE_EXT) {
- offset++;
- proto_tree_add_uint(ext_tree, hf_a11_ext_len, tvb, offset, 2, ext_len);
- offset+=2;
- }
- else if (ext_type != GEN_AUTH_EXT) {
- /* Another nasty hack since GEN_AUTH_EXT broke everything */
- proto_tree_add_uint(ext_tree, hf_a11_ext_len, tvb, offset, 1, ext_len);
- offset++;
- }
-
- switch(ext_type) {
- case SS_EXT:
- proto_tree_add_item(ext_tree, hf_a11_ses_ptype, tvb, offset, 2, FALSE);
- proto_tree_add_item(ext_tree, hf_a11_ses_key, tvb, offset+2, 4, FALSE);
- proto_tree_add_item(ext_tree, hf_a11_ses_sidver, tvb, offset+7, 1, FALSE);
- proto_tree_add_item(ext_tree, hf_a11_ses_mnsrid, tvb, offset+8, 2, FALSE);
- proto_tree_add_item(ext_tree, hf_a11_ses_msid_type, tvb, offset+10, 2, FALSE);
- proto_tree_add_item(ext_tree, hf_a11_ses_msid_len, tvb, offset+12, 1, FALSE);
- proto_tree_add_item(ext_tree, hf_a11_ses_msid, tvb, offset+13, ext_len-13, FALSE);
- break;
- case MH_AUTH_EXT:
- case MF_AUTH_EXT:
- case FH_AUTH_EXT:
- case RU_AUTH_EXT:
- /* All these extensions look the same. 4 byte SPI followed by a key */
- proto_tree_add_item(ext_tree, hf_a11_aext_spi, tvb, offset, 4, FALSE);
- proto_tree_add_item(ext_tree, hf_a11_aext_auth, tvb, offset+4, ext_len-4,
- FALSE);
- break;
- case MN_NAI_EXT:
- proto_tree_add_item(ext_tree, hf_a11_next_nai, tvb, offset,
- ext_len, FALSE);
- break;
-
- case GEN_AUTH_EXT: /* RFC 3012 */
- /*
- * Very nasty . . breaks normal extensions, since the length is
- * in the wrong place :(
- */
- proto_tree_add_uint(ext_tree, hf_a11_ext_stype, tvb, offset, 1, ext_subtype);
- offset++;
- proto_tree_add_uint(ext_tree, hf_a11_ext_len, tvb, offset, 2, ext_len);
- offset+=2;
- /* SPI */
- proto_tree_add_item(ext_tree, hf_a11_aext_spi, tvb, offset, 4, FALSE);
- /* Key */
- proto_tree_add_item(ext_tree, hf_a11_aext_auth, tvb, offset + 4,
- ext_len - 4, FALSE);
-
- break;
- case OLD_CVSE_EXT: /* RFC 3115 */
- case CVSE_EXT: /* RFC 3115 */
- proto_tree_add_item(ext_tree, hf_a11_vse_vid, tvb, offset, 4, FALSE);
- proto_tree_add_item(ext_tree, hf_a11_vse_apptype, tvb, offset+4, 2, FALSE);
- apptype = tvb_get_ntohs(tvb, offset+4);
+ switch(ext_type) {
+ case SS_EXT:
+ if (ext_len < 2)
+ break;
+ proto_tree_add_item(ext_tree, hf_a11_ses_ptype, tvb, offset, 2, FALSE);
+ offset += 2;
+ ext_len -= 2;
+ if (ext_len < 4)
+ break;
+ proto_tree_add_item(ext_tree, hf_a11_ses_key, tvb, offset, 4, FALSE);
+ offset += 4;
+ ext_len -= 4;
+ if (ext_len < 2)
+ break;
+ proto_tree_add_item(ext_tree, hf_a11_ses_sidver, tvb, offset+1, 1, FALSE);
+ offset += 2;
+ ext_len -= 2;
+ if (ext_len < 2)
+ break;
+ proto_tree_add_item(ext_tree, hf_a11_ses_mnsrid, tvb, offset, 2, FALSE);
+ offset += 2;
+ ext_len -= 2;
+ proto_tree_add_item(ext_tree, hf_a11_ses_msid_type, tvb, offset, 2, FALSE);
+ offset += 2;
+ ext_len -= 2;
+ if (ext_len < 1)
+ break;
+ proto_tree_add_item(ext_tree, hf_a11_ses_msid_len, tvb, offset, 1, FALSE);
+ offset += 1;
+ ext_len -= 1;
+ if (ext_len == 0)
+ break;
+ proto_tree_add_item(ext_tree, hf_a11_ses_msid, tvb, offset, ext_len, FALSE);
+ break;
+ case MH_AUTH_EXT:
+ case MF_AUTH_EXT:
+ case FH_AUTH_EXT:
+ case RU_AUTH_EXT:
+ /* All these extensions look the same. 4 byte SPI followed by a key */
+ if (ext_len < 4)
+ break;
+ proto_tree_add_item(ext_tree, hf_a11_aext_spi, tvb, offset, 4, FALSE);
+ offset += 4;
+ ext_len -= 4;
+ if (ext_len == 0)
+ break;
+ proto_tree_add_item(ext_tree, hf_a11_aext_auth, tvb, offset, ext_len,
+ FALSE);
+ break;
+ case MN_NAI_EXT:
+ if (ext_len == 0)
+ break;
+ proto_tree_add_item(ext_tree, hf_a11_next_nai, tvb, offset,
+ ext_len, FALSE);
+ break;
+
+ case GEN_AUTH_EXT: /* RFC 3012 */
+ /*
+ * Very nasty . . breaks normal extensions, since the length is
+ * in the wrong place :(
+ */
+ proto_tree_add_uint(ext_tree, hf_a11_ext_stype, tvb, offset, 1, ext_subtype);
+ offset++;
+ proto_tree_add_uint(ext_tree, hf_a11_ext_len, tvb, offset, 2, ext_len);
+ offset+=2;
+ /* SPI */
+ if (ext_len < 4)
+ break;
+ proto_tree_add_item(ext_tree, hf_a11_aext_spi, tvb, offset, 4, FALSE);
+ offset += 4;
+ ext_len -= 4;
+ /* Key */
+ if (ext_len == 0)
+ break;
+ proto_tree_add_item(ext_tree, hf_a11_aext_auth, tvb, offset,
+ ext_len, FALSE);
+
+ break;
+ case OLD_CVSE_EXT: /* RFC 3115 */
+ case CVSE_EXT: /* RFC 3115 */
+ if (ext_len < 4)
+ break;
+ proto_tree_add_item(ext_tree, hf_a11_vse_vid, tvb, offset, 4, FALSE);
+ offset += 4;
+ ext_len -= 4;
+ if (ext_len < 2)
+ break;
+ apptype = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_uint(ext_tree, hf_a11_vse_apptype, tvb, offset, 2, apptype);
+ offset += 2;
+ ext_len -= 2;
if(apptype == 0x0101) {
if (tvb_reported_length_remaining(tvb, offset) > 0) {
- dissect_a11_radius(tvb, offset+6, ext_tree, ext_len + hdrLen - 8);
+ dissect_a11_radius(tvb, offset, ext_tree, ext_len + 2);
}
}
- break;
- case OLD_NVSE_EXT: /* RFC 3115 */
- case NVSE_EXT: /* RFC 3115 */
- proto_tree_add_item(ext_tree, hf_a11_vse_vid, tvb, offset+2, 4, FALSE);
- proto_tree_add_item(ext_tree, hf_a11_vse_apptype, tvb, offset+6, 2, FALSE);
-
- apptype = tvb_get_ntohs(tvb, offset+6);
+ break;
+ case OLD_NVSE_EXT: /* RFC 3115 */
+ case NVSE_EXT: /* RFC 3115 */
+ if (ext_len < 6)
+ break;
+ proto_tree_add_item(ext_tree, hf_a11_vse_vid, tvb, offset+2, 4, FALSE);
+ offset += 6;
+ ext_len -= 6;
+ proto_tree_add_item(ext_tree, hf_a11_vse_apptype, tvb, offset, 2, FALSE);
+
+ if (ext_len < 2)
+ break;
+ apptype = tvb_get_ntohs(tvb, offset);
+ offset += 2;
+ ext_len -= 2;
switch(apptype) {
case 0x0401:
- proto_tree_add_item(ext_tree, hf_a11_vse_panid, tvb, offset+8, 5, FALSE);
- proto_tree_add_item(ext_tree, hf_a11_vse_canid, tvb, offset+13, 5, FALSE);
+ if (ext_len < 5)
+ break;
+ proto_tree_add_item(ext_tree, hf_a11_vse_panid, tvb, offset, 5, FALSE);
+ offset += 5;
+ ext_len -= 5;
+ if (ext_len < 5)
+ break;
+ proto_tree_add_item(ext_tree, hf_a11_vse_canid, tvb, offset, 5, FALSE);
break;
case 0x0501:
- proto_tree_add_item(ext_tree, hf_a11_vse_ppaddr, tvb, offset+8, 4, FALSE);
+ if (ext_len < 4)
+ break;
+ proto_tree_add_item(ext_tree, hf_a11_vse_ppaddr, tvb, offset, 4, FALSE);
break;
case 0x0601:
- proto_tree_add_item(ext_tree, hf_a11_vse_dormant, tvb, offset+8, 2, FALSE);
+ if (ext_len < 2)
+ break;
+ proto_tree_add_item(ext_tree, hf_a11_vse_dormant, tvb, offset, 2, FALSE);
break;
case 0x0701:
- proto_tree_add_item(ext_tree, hf_a11_vse_code, tvb, offset+8, 1, FALSE);
+ if (ext_len < 1)
+ break;
+ proto_tree_add_item(ext_tree, hf_a11_vse_code, tvb, offset, 1, FALSE);
break;
case 0x0801:
- proto_tree_add_item(ext_tree, hf_a11_vse_pdit, tvb, offset+8, 1, FALSE);
+ if (ext_len < 1)
+ break;
+ proto_tree_add_item(ext_tree, hf_a11_vse_pdit, tvb, offset, 1, FALSE);
break;
case 0x0802:
- proto_tree_add_text(ext_tree, tvb, offset+8, -1, "Session Parameter - Always On");
+ proto_tree_add_text(ext_tree, tvb, offset, -1, "Session Parameter - Always On");
break;
case 0x0901:
- proto_tree_add_item(ext_tree, hf_a11_vse_srvopt, tvb, offset+8, 2, FALSE);
+ if (ext_len < 2)
+ break;
+ proto_tree_add_item(ext_tree, hf_a11_vse_srvopt, tvb, offset, 2, FALSE);
break;
}
- break;
- case MF_CHALLENGE_EXT: /* RFC 3012 */
- /* The default dissector is good here. The challenge is all hex anyway. */
- default:
- proto_tree_add_item(ext_tree, hf_a11_ext, tvb, offset, ext_len, FALSE);
- break;
- } /* ext type */
+ break;
+ case MF_CHALLENGE_EXT: /* RFC 3012 */
+ /* The default dissector is good here. The challenge is all hex anyway. */
+ default:
+ proto_tree_add_item(ext_tree, hf_a11_ext, tvb, offset, ext_len, FALSE);
+ break;
+ } /* ext type */
- offset += ext_len;
+ offset += ext_len;
} /* while data remaining */
} /* dissect_a11_extensions */