Wireshark-dev: [Wireshark-dev] [PATCH] LIBNDR_FLAG_NOALIGN support in wireshark and PIDL
From: Julien Kerihuel <j.kerihuel@xxxxxxxxxxxxxx>
Date: Mon, 18 Jan 2010 15:25:35 +0100
Hi Lists,

Prior submitting the wireshark's part of this patch onto the wireshark bugzilla, I thought it might be worthwhile to have feedback from developers first.

MAPI content is non-NDR compatible. It can be dissected using the existing NDR layer functions in epan/dissectors/packet-dcerpc-ndr.c but it requires offsets to be left intact prior effective dissection, which means there shouldn't be any offset adjustment when LIBNDR_FLAG_NOALIGN flag is used in PIDL.

The following patches implement such behavior:
1. It adds a no_align gboolean variable to dcerpc_info structure (default set to FALSE)
2. when pidl generates the code and LIBNDR_FLAG_NOALIGN flag is used, it sets the no_align gboolean to TRUE which turns offste adjustment off in wireshark.

I couldn't come up with a nicer solution so far, but these tiny patches truly improves the overall development effort for the MAPI dissector. It basically prevents from writing hand-written code for most of the MAPI calls. This also means this may help keeping the conformance files - in particular request.cnf.c and response.cnf.c - readable and prevent them from exponentially growing up.

Another advantage is that it becomes conceivable to generate code for structures or others some non-dceprc dissectors using pidl. You would only have to describe the structures, specify LIBNDR_FLAG_NOALIGN flag and you would have automatic dissection code generated which you can refer to (or cut and paste).

Cheers,
Julien.

---

Julien Kerihuel
j.kerihuel@xxxxxxxxxxxxxx
OpenChange Project Manager

GPG Fingerprint: 0B55 783D A781 6329 108A  B609 7EF6 FE11 A35F 1F79


Index: epan/dissectors/packet-dcerpc-ndr.c
===================================================================
--- epan/dissectors/packet-dcerpc-ndr.c	(revision 31523)
+++ epan/dissectors/packet-dcerpc-ndr.c	(working copy)
@@ -129,7 +129,7 @@
     }
 
 
-    if (offset % 2) {
+    if (!di->no_align && (offset % 2)) {
         offset++;
     }
     return dissect_dcerpc_uint16 (tvb, offset, pinfo,
@@ -151,7 +151,7 @@
     }
 
 
-    if (offset % 2) {
+    if (!di->no_align && (offset % 2)) {
         offset++;
     }
     offset=dissect_dcerpc_uint16 (tvb, offset, pinfo,
@@ -207,7 +207,7 @@
     }
 
 
-    if (offset % 4) {
+    if (!di->no_align && (offset % 4)) {
         offset += 4 - (offset % 4);
     }
     return dissect_dcerpc_uint32 (tvb, offset, pinfo,
@@ -277,7 +277,7 @@
     }
 
 
-    if (offset % 4) {
+    if (!di->no_align && (offset % 4)) {
         offset += 4 - (offset % 4);
     }
     offset=dissect_dcerpc_uint32 (tvb, offset, pinfo,
@@ -337,7 +337,7 @@
       return offset;
     }
 
-    if (offset % 4) {
+    if (!di->no_align && (offset % 4)) {
         offset += 4 - (offset % 4);
     }
     return dissect_dcerpc_uint64 (tvb, offset, pinfo,
@@ -360,7 +360,7 @@
       return offset;
     }
 
-    if (offset % 8) {
+    if (!di->no_align && (offset % 8)) {
         offset += 8 - (offset % 8);
     }
     return dissect_dcerpc_uint64 (tvb, offset, pinfo,
@@ -381,7 +381,7 @@
       return offset;
     }
 
-    if (offset % 8) {
+    if (!di->no_align && (offset % 8)) {
         offset += 8 - (offset % 8);
     }
     offset=dissect_dcerpc_uint64 (tvb, offset, pinfo,
@@ -437,7 +437,7 @@
       return offset;
     }
 
-    if (offset % 4) {
+    if (!di->no_align && (offset % 4)) {
         offset += 4 - (offset % 4);
     }
     return dissect_dcerpc_float(tvb, offset, pinfo,
@@ -459,7 +459,7 @@
       return offset;
     }
 
-    if (offset % 8) {
+    if (!di->no_align && (offset % 8)) {
         offset += 8 - (offset % 8);
     }
     return dissect_dcerpc_double(tvb, offset, pinfo,
@@ -481,7 +481,7 @@
     }
 
 
-    if (offset % 4) {
+    if (!di->no_align && (offset % 4)) {
         offset += 4 - (offset % 4);
     }
     return dissect_dcerpc_time_t (tvb, offset, pinfo,
@@ -502,7 +502,7 @@
     }
 
     /* uuid's are aligned to 4 bytes, due to initial uint32 in struct */
-    if (offset % 4) {
+    if (!di->no_align && (offset % 4)) {
         offset += 4 - (offset % 4);
     }
     return dissect_dcerpc_uuid_t (tvb, offset, pinfo,
@@ -532,7 +532,7 @@
       return offset;
     }
 
-    if (offset % 4) {
+    if (!di->no_align && (offset % 4)) {
         offset += 4 - (offset % 4);
     }
     ctx_hnd.attributes = dcerpc_tvb_get_ntohl (tvb, offset, drep);
Index: epan/dissectors/packet-dcerpc.h
===================================================================
--- epan/dissectors/packet-dcerpc.h	(revision 31523)
+++ epan/dissectors/packet-dcerpc.h	(working copy)
@@ -325,6 +331,7 @@
 	guint16 smb_fid;	/* FID for DCERPC over SMB */
 	guint8 ptype;       /* packet type: PDU_REQ, PDU_RESP, ... */
 	gboolean conformant_run;
+	gboolean no_align; /* are data aligned? (default yes) */
 	gint32 conformant_eaten; /* how many bytes did the conformant run eat?*/
 	guint32 array_max_count;	/* max_count for conformant arrays */
 	guint32 array_max_count_offset;
Index: lib/Parse/Pidl/Wireshark/NDR.pm
===================================================================
--- lib/Parse/Pidl/Wireshark/NDR.pm	(revision 20)
+++ lib/Parse/Pidl/Wireshark/NDR.pm	(revision 21)
@@ -642,7 +642,11 @@
 		$self->pidl_code($type . " " . $_->{NAME} . "_array_len;");
 	    }
 	}
-		
+
+	if (property_matches($e->{ORIGINAL}, 'flag', '.*LIBNDR_FLAG_NOALIGN.*')) {
+	    $self->pidl_code("dcerpc_info *di = pinfo->private_data;");
+	    $e->{ALIGN} = 0;
+	}
 	if ($e->{ALIGN} > 1) {
 		$self->pidl_code("dcerpc_info *di = pinfo->private_data;");
 	}
@@ -651,6 +655,8 @@
 
 	if ($e->{ALIGN} > 1) {
 		$self->pidl_code("ALIGN_TO_$e->{ALIGN}_BYTES;");
+	} elsif (property_matches($e->{ORIGINAL}, 'flag', 'LIBNDR_FLAG_NOALIGN')) {
+	    $self->pidl_code("di->no_align = TRUE;");
 	}
 	$self->pidl_code("");
 
@@ -673,6 +679,8 @@
 		$self->pidl_code("ALIGN_TO_$e->{ALIGN}_BYTES;");
 		$self->deindent;
 		$self->pidl_code("}");
+	} elsif (property_matches($e->{ORIGINAL}, 'flag', 'LIBNDR_FLAG_NOALIGN')) {
+	    $self->pidl_code("di->no_align = FALSE;");
 	}
 	$self->pidl_code("");
 	$self->pidl_code("return offset;");
@@ -729,6 +737,12 @@
 	$self->pidl_code("proto_tree *tree = NULL;");
 	$self->pidl_code("int old_offset;");
 	$self->pidl_code("$switch_type level;");
+	if (property_matches($e->{ORIGINAL}, 'flag', '.*LIBNDR_FLAG_NOALIGN.*')) {
+	    $self->pidl_code("dcerpc_info *di = pinfo->private_data;");
+	    $e->{ALIGN} = 0;
+	    $self->pidl_code("");
+	    $self->pidl_code("di->no_align = TRUE;");
+	}
 	$self->pidl_code("");
 
 	$self->pidl_code("old_offset = offset;");
@@ -757,6 +771,8 @@
 	$self->pidl_code("proto_item_set_len(item, offset-old_offset);\n");
 	$self->pidl_code("");
 
+	$self->pidl_code("di->no_align = FALSE;") if (property_matches($e->{ORIGINAL}, 'flag', '.*LIBNDR_FLAG_NOALIGN.*'));
+
 	$self->pidl_code("return offset;");
 	$self->deindent;
 	$self->pidl_code("}");

Attachment: signature.asc
Description: This is a digitally signed message part