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):