pidl-wireshark: Display Array as block instead of bytes by bytes
authorMatthieu Patou <mat@matws.net>
Thu, 3 Oct 2013 08:33:43 +0000 (01:33 -0700)
committerStefan Metzmacher <metze@samba.org>
Mon, 4 Nov 2013 11:19:26 +0000 (12:19 +0100)
pidl/lib/Parse/Pidl/Wireshark/NDR.pm

index 99e358b482757364fbe53711e5bb0ba8eaf0de1b..503ce66598c1c19344a776fb702d1a2fe1a3d4ff 100644 (file)
@@ -69,7 +69,7 @@ sub new($)
 {
        my ($class) = @_;
        my $self = {res => {hdr => "", def => "", code => ""}, tabs => "", cur_fn => undef,
-               hf_used => {}, ett => [], conformance => undef
+               hf_used => {}, ett => [], conformance => undef, block_display => [],
 
        };
        bless($self, $class);
@@ -297,16 +297,31 @@ sub ElementLevel($$$$$$$$)
                if ($l->{IS_INLINE}) {
                        error($e->{ORIGINAL}, "Inline arrays not supported");
                } elsif ($l->{IS_FIXED}) {
-                       $self->pidl_code("int i;");
-                       $self->pidl_code("for (i = 0; i < $l->{SIZE_IS}; i++)");
-                       $self->pidl_code("\toffset = $myname\_(tvb, offset, pinfo, tree, drep);");
+                       $self->pidl_code("dcerpc_info *di = (dcerpc_info*)pinfo->private_data;");
+                       $self->pidl_code("int conformant = di->conformant_run;");
+
+                       my $additional = "";
+                       if ($e->{TYPE} eq "uint8") {
+                               push @{$self->{block_display}} , int($e);
+                               $additional = " $l->{SIZE_IS},";
+                       }
+                       $self->pidl_code("if (!conformant) {");
+                       $self->indent;
+                       $self->pidl_code("offset = $myname\_(tvb, offset,$additional pinfo, tree, drep);");
+                       $self->deindent;
+                       $self->pidl_code("}");
                } else {
                        my $type = "";
                        $type .= "c" if ($l->{IS_CONFORMANT});
                        $type .= "v" if ($l->{IS_VARYING});
 
                        unless ($l->{IS_ZERO_TERMINATED}) {
-                               $self->pidl_code("offset = dissect_ndr_u" . $type . "array(tvb, offset, pinfo, tree, drep, $myname\_);");
+                               my $suffix = "";
+                               if ($e->{TYPE} eq "uint8" && !$l->{IS_SURROUNDING}) {
+                                       $suffix = "_block";
+                                       push @{$self->{block_display}} , int($e);
+                               }
+                               $self->pidl_code("offset = dissect_ndr_u" . $type . "array$suffix(tvb, offset, pinfo, tree, drep, $myname\_);");
                        } else {
                                my $nl = GetNextLevel($e,$l);
                                $self->pidl_code("char *data;");
@@ -353,11 +368,15 @@ sub ElementLevel($$$$$$$$)
                                $self->{conformance}->{imports}->{"$pn.$e->{NAME}"}->{USED} = 1;
 
                        } elsif (defined($self->{conformance}->{types}->{$l->{DATA_TYPE}})) {
-                               $call= $self->{conformance}->{types}->{$l->{DATA_TYPE}}->{DISSECTOR_NAME};
-                               $self->{conformance}->{types}->{$l->{DATA_TYPE}}->{USED} = 1;
+                               my $ref_e = int($e);
+                               if (grep /$ref_e/,@{$self->{block_display}}) {
+                                       $call = "proto_tree_add_bytes(tree, \@HF\@, tvb, offset, length, tvb_get_ptr(tvb, offset,length)); offset += length;";
+                               } else {
+                                       $call= $self->{conformance}->{types}->{$l->{DATA_TYPE}}->{DISSECTOR_NAME};
+                                       $self->{conformance}->{types}->{$l->{DATA_TYPE}}->{USED} = 1;
+                               }
                        } else {
                                $self->pidl_code("offset = $ifname\_dissect_struct_" . $l->{DATA_TYPE} . "(tvb,offset,pinfo,tree,drep,$hf,$param);");
-
                                return;
                        }
 
@@ -473,10 +492,17 @@ sub Element($$$$$)
                        $param = "*$param";
                }
                next if ($_->{TYPE} eq "SWITCH");
-               $self->pidl_def("static int $dissectorname$add(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, guint8 *drep _U_$moreparam);");
+               my $additionalparam = "";
+
+               my $ref_e = int($e);
+               if (grep /$ref_e/, @{$self->{block_display}}) {
+                       $additionalparam = "int length _U_,";
+                       $self->change_hf_field_type("hf_$ifname\_$pn\_$e->{NAME}", "FT_BYTES", "BASE_NONE");
+               }
+               $self->pidl_def("static int $dissectorname$add(tvbuff_t *tvb _U_, int offset _U_,$additionalparam packet_info *pinfo _U_, proto_tree *tree _U_, guint8 *drep _U_$moreparam);");
                $self->pidl_fn_start("$dissectorname$add");
                $self->pidl_code("static int");
-               $self->pidl_code("$dissectorname$add(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, guint8 *drep _U_$moreparam)");
+               $self->pidl_code("$dissectorname$add(tvbuff_t *tvb _U_, int offset _U_,$additionalparam packet_info *pinfo _U_, proto_tree *tree _U_, guint8 *drep _U_$moreparam)");
                $self->pidl_code("{");
                $self->indent;
 
@@ -491,8 +517,15 @@ sub Element($$$$$)
                $self->pidl_code("}\n");
                $self->pidl_fn_end("$dissectorname$add");
                $add.="_";
+               # Reset at the end of the loop
+               $additionalparam = "";
+               if ($_->{TYPE} eq "ARRAY" or $_->{TYPE} eq "SWITCH") {
+                       $moreparam = "";
+                       $param = "0";
+               }
                last if ($_->{TYPE} eq "ARRAY" and $_->{IS_ZERO_TERMINATED});
        }
+       pop @{$self->{block_display}} if (scalar(@{$self->{block_display}}));
 
        return $call_code;
 }