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.
---
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
- Follow-Ups:
- Re: [Wireshark-dev] [PATCH] LIBNDR_FLAG_NOALIGN support in wireshark and PIDL
- From: ronnie sahlberg
- Re: [Wireshark-dev] [PATCH] LIBNDR_FLAG_NOALIGN support in wireshark and PIDL
- Prev by Date: Re: [Wireshark-dev] No plugins loaded as 'root' user
- Next by Date: [Wireshark-dev] Move from C89 to C99?
- Previous by thread: Re: [Wireshark-dev] No plugins loaded as 'root' user
- Next by thread: Re: [Wireshark-dev] [PATCH] LIBNDR_FLAG_NOALIGN support in wireshark and PIDL
- Index(es):