Ethereal-dev: [Ethereal-dev] Updates to spoolss dissector
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Tim Potter <tpot@xxxxxxxxx>
Date: Fri, 4 Jan 2002 17:05:43 +1100
Hello again. This patch fixes some crash bugs in the spoolss dissector and adds a few more random things. Tim. - functions that return a range of uint8,16,32 bytes have a check so as not to pass a negative count value to tvb_get_ptr() - when iterating over a list of defered pointers, don't return a zero length list of return values but rather NULL - handle NULL relative strings - start of dissector for a PRINTER_INFO_2 structure - when parsing the data in a BUFFER_DATA structure, insert the data item in the correct subtree and pass the correct item pointer back in the return value - don't crash if no buffer data is returned in a GetPrinter response - dissect AddPrinterEx, AddPrinterDriver query - dissect AddPrinterDriver, AddForm reply - display value data in EnumPrinterData reply - don't forget to register SPOOL_PRINTER_INFO_LEVEL subtree
? diff.out
Index: packet-dcerpc-nt.c
===================================================================
RCS file: /cvsroot/ethereal/packet-dcerpc-nt.c,v
retrieving revision 1.2
diff -u -r1.2 packet-dcerpc-nt.c
--- packet-dcerpc-nt.c 2002/01/03 20:42:40 1.2
+++ packet-dcerpc-nt.c 2002/01/04 05:53:16
@@ -75,6 +75,11 @@
{
const guint8 *ptr;
+ /* The tvb_get_ptr() function fails an assertion if count < -1 */
+
+ if (count < -1)
+ THROW(BoundsError);
+
/* No alignment required */
ptr = tvb_get_ptr(tvb, offset, count);
@@ -118,6 +123,11 @@
{
const guint8 *ptr;
+ /* The tvb_get_ptr() function fails an assertion if count < -1 */
+
+ if (count < -1)
+ THROW(BoundsError);
+
offset = prs_align(offset, 2);
ptr = tvb_get_ptr(tvb, offset, count * 2);
@@ -162,6 +172,11 @@
{
const guint8 *ptr;
+ /* The tvb_get_ptr() function fails an assertion if count < -1 */
+
+ if (count < -1)
+ THROW(BoundsError);
+
offset = prs_align(offset, 4);
ptr = tvb_get_ptr(tvb, offset, count * 4);
Index: packet-dcerpc-spoolss.c
===================================================================
RCS file: /cvsroot/ethereal/packet-dcerpc-spoolss.c,v
retrieving revision 1.2
diff -u -r1.2 packet-dcerpc-spoolss.c
--- packet-dcerpc-spoolss.c 2002/01/03 20:42:40 1.2
+++ packet-dcerpc-spoolss.c 2002/01/04 05:53:16
@@ -426,13 +426,18 @@
void ***ptr_data)
{
struct deferred_ptr_state s;
- int new_offset = offset, list_len;
+ int new_offset = offset;
/* Create a list of void pointers to store return data */
if (ptr_data) {
- list_len = g_list_length(*dp_list);
- *ptr_data = malloc(list_len * sizeof(void *));
+ int len = g_list_length(*dp_list) * sizeof(void *);
+
+ if (len > 0) {
+ *ptr_data = malloc(len);
+ memset(*ptr_data, 0, len);
+ } else
+ *ptr_data = NULL;
}
/* Set up iterator data */
@@ -1108,16 +1113,21 @@
proto_tree *subtree;
guint32 relstr_offset, relstr_start, relstr_end;
guint16 *ptr;
- char *text;
+ char *text = strdup("NULL");
gint len = 0, remaining, i;
offset = prs_uint32(tvb, offset, pinfo, tree, &relstr_offset, NULL);
- relstr_start = relstr_offset + struct_start;
+ /* A relative offset of zero is a NULL string */
- relstr_end = prs_uint16uni(tvb, relstr_start, pinfo, tree,
- (void **)&text, NULL);
-
+ relstr_start = relstr_offset + struct_start;
+
+ if (relstr_offset)
+ relstr_end = prs_uint16uni(tvb, relstr_start, pinfo, tree,
+ (void **)&text, NULL);
+ else
+ relstr_end = offset;
+
item = proto_tree_add_text(tree, tvb, relstr_start,
relstr_end - relstr_start, "%s: %s",
name ? name : "RELSTR", text);
@@ -1222,6 +1232,29 @@
static int prs_PRINTER_INFO_2(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, GList **dp_list, void **data)
{
+ int struct_start = offset;
+
+ offset = prs_relstr(tvb, offset, pinfo, tree, dp_list, struct_start,
+ NULL, "Server name");
+
+ offset = prs_relstr(tvb, offset, pinfo, tree, dp_list, struct_start,
+ NULL, "Printer name");
+
+ offset = prs_relstr(tvb, offset, pinfo, tree, dp_list, struct_start,
+ NULL, "Share name");
+
+ offset = prs_relstr(tvb, offset, pinfo, tree, dp_list, struct_start,
+ NULL, "Port name");
+
+ offset = prs_relstr(tvb, offset, pinfo, tree, dp_list, struct_start,
+ NULL, "Driver name");
+
+ offset = prs_relstr(tvb, offset, pinfo, tree, dp_list, struct_start,
+ NULL, "Comment");
+
+ offset = prs_relstr(tvb, offset, pinfo, tree, dp_list, struct_start,
+ NULL, "Location");
+
return offset;
}
@@ -1825,7 +1858,7 @@
static int prs_BUFFER_DATA(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, GList **dp_list, void **data)
{
- proto_item *item;
+ proto_item *item, *subitem;
proto_tree *subtree, *subsubtree;
guint32 ptr = 0, size;
guint8 *data8;
@@ -1836,9 +1869,9 @@
offset = prs_uint32(tvb, offset, pinfo, subtree, &size, "Size");
- item = proto_tree_add_text(subtree, tvb, offset, size, "Data");
+ subitem = proto_tree_add_text(subtree, tvb, offset, size, "Data");
- subsubtree = proto_item_add_subtree(item, ett_BUFFER_DATA_BUFFER);
+ subsubtree = proto_item_add_subtree(subitem, ett_BUFFER_DATA_BUFFER);
offset = prs_uint8s(tvb, offset, pinfo, subsubtree, size, &data8,
NULL);
@@ -1852,7 +1885,7 @@
bd = (struct BUFFER_DATA *)malloc(sizeof(struct BUFFER_DATA));
bd->data8 = data8;
- bd->item = item;
+ bd->item = subitem;
bd->tree = subsubtree;
bd->tvb = tvb;
bd->offset = offset - size;
@@ -1949,7 +1982,7 @@
request_hash_value *request_info;
GList *dp_list = NULL;
void **data_list;
- struct BUFFER_DATA *bd;
+ struct BUFFER_DATA *bd = NULL;
guint8 *data8;
/* Update informational fields */
@@ -1969,9 +2002,10 @@
prs_BUFFER, (void **)&data8,
&data_list);
- bd = (struct BUFFER_DATA *)data_list[0];
+ if (data_list)
+ bd = (struct BUFFER_DATA *)data_list[0];
- if (bd->tree && request_info) {
+ if (bd && bd->tree && request_info) {
gint16 level = request_info->data.GetPrinter.level;
proto_item_append_text(bd->item, ", PRINTER_INFO_%d", level);
@@ -1981,6 +2015,11 @@
prs_PRINTER_INFO_0(bd->tvb, bd->offset, pinfo,
bd->tree, &dp_list, NULL);
break;
+
+ case 2:
+ prs_PRINTER_INFO_2(bd->tvb, bd->offset, pinfo,
+ bd->tree, &dp_list, NULL);
+ break;
default:
proto_tree_add_text(tree, tvb, offset, 0,
@@ -2273,6 +2312,58 @@
* AddPrinterEx
*/
+static int SpoolssAddPrinterEx_q(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree,
+ char *drep)
+{
+ dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
+ request_hash_value *request_info;
+ guint32 ptr;
+ char *printer_name;
+
+ /* Update informational fields */
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_set_str(pinfo->cinfo, COL_INFO, "AddPrinterEx request");
+
+ request_info = fetch_request_info(pinfo, di, SPOOLSS_DUMMY);
+
+ if (request_info)
+ add_request_text(tree, tvb, offset, request_info);
+ else
+ store_request_info_none(pinfo, di);
+
+ /* Parse packet */
+
+ offset = prs_ptr(tvb, offset, pinfo, tree, &ptr, "Server name");
+
+ if (ptr) {
+ offset = prs_struct_and_referents(tvb, offset, pinfo, tree,
+ prs_UNISTR2_dp,
+ (void *)&printer_name, NULL);
+ }
+
+ offset = prs_uint32(tvb, offset, pinfo, tree, NULL, "Level");
+
+ /* PRINTER INFO LEVEL */
+
+ offset = prs_uint32(tvb, offset, pinfo, tree, NULL, "Unknown");
+ offset = prs_uint32(tvb, offset, pinfo, tree, NULL, "Unknown");
+ offset = prs_uint32(tvb, offset, pinfo, tree, NULL, "Unknown");
+ offset = prs_uint32(tvb, offset, pinfo, tree, NULL, "Unknown");
+
+ offset = prs_uint32(tvb, offset, pinfo, tree, NULL, "User switch");
+
+ /* USER LEVEL */
+
+ if (tvb_length_remaining(tvb, offset) != 0)
+ proto_tree_add_text(tree, tvb, offset, 0,
+ "[Long frame (%d bytes): SPOOLSS]",
+ tvb_length_remaining(tvb, offset));
+
+ return offset;
+}
+
static int SpoolssAddPrinterEx_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, char *drep)
{
@@ -2375,7 +2466,9 @@
{
dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
request_hash_value *request_info;
- guint32 data_size, type;
+ guint32 data_size, type, value_size;
+ guint16 *uint16s;
+ char *text;
/* Update informational fields */
@@ -2390,10 +2483,22 @@
request_info->response_num = pinfo->fd->num;
/* Parse packet */
-
- offset = prs_uint32(tvb, offset, pinfo, tree, NULL, "Value size");
- /* unistr2_dp */
+ offset = prs_uint32(tvb, offset, pinfo, tree, &value_size,
+ "Value size");
+
+ offset = prs_uint16s(tvb, offset, pinfo, tree, value_size, &uint16s,
+ NULL);
+
+ text = fake_unicode(uint16s, value_size);
+
+ proto_tree_add_text(tree, tvb, offset - value_size * 2,
+ value_size * 2, "Value: %s", text);
+
+ if (text[0] && check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", text);
+
+ free(text);
offset = prs_uint32(tvb, offset, pinfo, tree, NULL, "Real value size");
@@ -2506,6 +2611,104 @@
return offset;
}
+/*
+ * AddPrinterDriver
+ */
+
+static int SpoolssAddPrinterDriver_q(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree,
+ char *drep)
+{
+ dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
+ request_hash_value *request_info;
+
+ /* Update informational fields */
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_set_str(pinfo->cinfo, COL_INFO,
+ "AddPrinterDriver request");
+
+ request_info = fetch_request_info(pinfo, di, SPOOLSS_DUMMY);
+
+ if (request_info)
+ add_request_text(tree, tvb, offset, request_info);
+ else
+ store_request_info_none(pinfo, di);
+
+ /* Parse packet */
+
+ if (tvb_length_remaining(tvb, offset) != 0)
+ proto_tree_add_text(tree, tvb, offset, 0,
+ "[Long frame (%d bytes): SPOOLSS]",
+ tvb_length_remaining(tvb, offset));
+
+ return offset;
+}
+
+static int SpoolssAddPrinterDriver_r(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree,
+ char *drep)
+{
+ dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
+ request_hash_value *request_info;
+
+ /* Update informational fields */
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_set_str(pinfo->cinfo, COL_INFO,
+ "AddPrinterDriver response");
+
+ request_info = fetch_request_info(pinfo, di, SPOOLSS_DUMMY);
+ add_response_text(tree, tvb, offset, request_info);
+
+ if (request_info)
+ request_info->response_num = pinfo->fd->num;
+
+ /* Parse packet */
+
+ offset = prs_werror(tvb, offset, pinfo, tree, NULL);
+
+ if (tvb_length_remaining(tvb, offset) != 0)
+ proto_tree_add_text(tree, tvb, offset, 0,
+ "[Long frame (%d bytes): SPOOLSS]",
+ tvb_length_remaining(tvb, offset));
+
+ return offset;
+}
+
+/*
+ * AddForm
+ */
+
+static int SpoolssAddForm_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, char *drep)
+{
+ dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
+ request_hash_value *request_info;
+
+ /* Update informational fields */
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_set_str(pinfo->cinfo, COL_INFO, "AddForm response");
+
+ request_info = fetch_request_info(pinfo, di, SPOOLSS_DUMMY);
+ add_response_text(tree, tvb, offset, request_info);
+
+ if (request_info)
+ request_info->response_num = pinfo->fd->num;
+
+ /* Parse packet */
+
+ offset = prs_werror(tvb, offset, pinfo, tree, NULL);
+
+ if (tvb_length_remaining(tvb, offset) != 0)
+ proto_tree_add_text(tree, tvb, offset, 0,
+ "[Long frame (%d bytes): SPOOLSS]",
+ tvb_length_remaining(tvb, offset));
+
+ return offset;
+}
+
#if 0
/* Templates for new subdissectors */
@@ -2588,7 +2791,8 @@
SpoolssSetPrinter_q, SpoolssSetPrinter_r },
{ SPOOLSS_GETPRINTER, "SPOOLSS_GETPRINTER",
SpoolssGetPrinter_q, SpoolssGetPrinter_r },
- { SPOOLSS_ADDPRINTERDRIVER, "SPOOLSS_ADDPRINTERDRIVER", NULL, NULL },
+ { SPOOLSS_ADDPRINTERDRIVER, "SPOOLSS_ADDPRINTERDRIVER",
+ NULL, SpoolssAddPrinterDriver_r },
{ SPOOLSS_ENUMPRINTERDRIVERS, "SPOOLSS_ENUMPRINTERDRIVERS", NULL, NULL },
{ SPOOLSS_GETPRINTERDRIVERDIRECTORY, "SPOOLSS_GETPRINTERDRIVERDIRECTORY", NULL, NULL },
{ SPOOLSS_DELETEPRINTERDRIVER, "SPOOLSS_DELETEPRINTERDRIVER", NULL, NULL },
@@ -2608,7 +2812,8 @@
SpoolssSetPrinterData_q, SpoolssSetPrinterData_r },
{ SPOOLSS_CLOSEPRINTER, "SPOOLSS_CLOSEPRINTER",
SpoolssClosePrinter_q, SpoolssClosePrinter_r },
- { SPOOLSS_ADDFORM, "SPOOLSS_ADDFORM", NULL, NULL },
+ { SPOOLSS_ADDFORM, "SPOOLSS_ADDFORM",
+ NULL, SpoolssAddForm_r },
{ SPOOLSS_DELETEFORM, "SPOOLSS_DELETEFORM", NULL, NULL },
{ SPOOLSS_GETFORM, "SPOOLSS_GETFORM", NULL, NULL },
{ SPOOLSS_SETFORM, "SPOOLSS_SETFORM", NULL, NULL },
@@ -2709,6 +2914,7 @@
&ett_BUFFER_DATA,
&ett_BUFFER_DATA_BUFFER,
&ett_UNISTR2,
+ &ett_SPOOL_PRINTER_INFO_LEVEL,
&ett_PRINTER_INFO_0,
&ett_PRINTER_INFO_1,
&ett_PRINTER_INFO_2,
- Follow-Ups:
- Re: [Ethereal-dev] Updates to spoolss dissector
- From: Gilbert Ramirez
- Re: [Ethereal-dev] Updates to spoolss dissector
- From: Guy Harris
- Re: [Ethereal-dev] Updates to spoolss dissector
- Prev by Date: Re: [Ethereal-dev] cannot link 0.9.0 command too long
- Next by Date: Re: [Ethereal-dev] Updates to spoolss dissector
- Previous by thread: RE: [Ethereal-dev] cannot link 0.9.0 command too long
- Next by thread: Re: [Ethereal-dev] Updates to spoolss dissector
- Index(es):