tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm ndr_generic_array
authorStefan Metzmacher <metze@samba.org>
Mon, 21 Mar 2022 23:18:07 +0000 (00:18 +0100)
committerStefan Metzmacher <metze@samba.org>
Thu, 3 Nov 2022 10:32:45 +0000 (11:32 +0100)
tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm

index 29c090d5af818263bd151b8399845cb17fe21e2a..6d6f23f49050f7076b69cfec8f7bc1aa84ef33d2 100644 (file)
@@ -332,17 +332,30 @@ sub ElementLevel($$$$$$$$)
                        $self->pidl_code("for (i = 0; i < $l->{SIZE_IS}; i++)");
                        $self->pidl_code("\toffset = $myname\_(tvb, offset, pinfo, tree, di, drep);");
                } else {
-                       my $type = "";
-                       $type .= "c" if ($l->{IS_CONFORMANT});
-                       $type .= "v" if ($l->{IS_VARYING});
+                       if ($l->{IS_ZERO_TERMINATED}) {
+                               $self->pidl_code("char *data = NULL;");
+                       }
+                       my $ngavar = "nga";
+                       if (!$l->{IS_SURROUNDING}) {
+                               $self->pidl_code("struct ndr_generic_array nga = { .is_conformant = FALSE, };");
+                               $ngavar = "&nga";
+                       }
+                       if (!$l->{IS_SURROUNDING} and $l->{IS_CONFORMANT}) {
+                               $self->pidl_code("");
+                               $self->pidl_code("offset = dissect_ndr_conformant_array_hdr(tvb, offset, pinfo, tree, di, drep, $ngavar);");
+                       }
+                       if ($l->{IS_VARYING}) {
+                               $self->pidl_code("");
+                               $self->pidl_code("offset = dissect_ndr_varying_array_hdr(tvb, offset, pinfo, tree, di, drep, $ngavar);");
+                       }
 
                        unless ($l->{IS_ZERO_TERMINATED}) {
-                               $self->pidl_code("offset = dissect_ndr_u" . $type . "array(tvb, offset, pinfo, tree, di, drep, $myname\_);");
+                               $self->pidl_code("");
+                               $self->pidl_code("offset = dissect_ndr_generic_array_bytes(tvb, offset, pinfo, tree, di, drep, $ngavar, $myname\_);");
                        } else {
                                my $nl = GetNextLevel($e,$l);
-                               $self->pidl_code("char *data;");
                                $self->pidl_code("");
-                               $self->pidl_code("offset = dissect_ndr_$type" . "string(tvb, offset, pinfo, tree, di, drep, sizeof(g$nl->{DATA_TYPE}), $hf, FALSE, &data);");
+                               $self->pidl_code("offset = dissect_ndr_generic_array_string(tvb, offset, pinfo, tree, di, drep, sizeof(g$nl->{DATA_TYPE}), $hf, FALSE, $ngavar, &data);");
                                $self->pidl_code("proto_item_append_text(tree, \": %s\", data);");
                        }
                }
@@ -472,7 +485,9 @@ sub Element($$$$$$)
        my $dissectorname = "$ifname\_dissect\_element\_".StripPrefixes($pn, $self->{conformance}->{strip_prefixes})."\_".StripPrefixes($e->{NAME}, $self->{conformance}->{strip_prefixes});
 
        my ($call_code, $moreparam);
+       my $l = @{$e->{LEVELS}}[0];
        my $param = 0;
+       my $moreparam_once = 0;
        if (defined $isoruseswitch) {
                my $type = $isoruseswitch->[0];
                my $name = $isoruseswitch->[1];
@@ -504,6 +519,11 @@ sub Element($$$$$$)
                } else {
                        $call_code = "offset = $dissectorname(tvb, offset, pinfo, tree, di, drep);";
                }
+       } elsif ($l->{IS_SURROUNDING} and $l->{IS_CONFORMANT}) {
+               my $cfvarname = "nga_$e->{NAME}";
+               $moreparam = ", struct ndr_generic_array *nga";
+               $moreparam_once = 1;
+               $call_code = "offset = $dissectorname(tvb, offset, pinfo, tree, di, drep, &$cfvarname);";
        } else {
                $moreparam = "";
                $call_code = "offset = $dissectorname(tvb, offset, pinfo, tree, di, drep);";
@@ -575,6 +595,7 @@ sub Element($$$$$$)
                $self->pidl_code("}\n");
                $self->pidl_fn_end("$dissectorname$add");
                $add.="_";
+               $moreparam="" if $moreparam_once;
                last if ($_->{TYPE} eq "ARRAY" and $_->{IS_ZERO_TERMINATED});
        }
 
@@ -771,6 +792,32 @@ sub Struct($$$$)
                $doalign = 0;
        }
 
+       my $cfdissectorname = undef;
+       my $cfvarname = undef;
+       if (defined $e->{SURROUNDING_ELEMENT}) {
+               my $se = $e->{SURROUNDING_ELEMENT};
+               my $pn = $name;
+               $cfdissectorname = "$ifname\_dissect\_conformant\_".StripPrefixes($pn, $self->{conformance}->{strip_prefixes})."\_".StripPrefixes($se->{NAME}, $self->{conformance}->{strip_prefixes});
+               $cfvarname = "nga_$se->{NAME}";
+               push @$vars, "struct ndr_generic_array $cfvarname = { .is_conformant = FALSE, };";
+               unless (defined($self->{conformance}->{noemit}->{"$cfdissectorname"})) {
+
+                       $self->pidl_def("static int $cfdissectorname(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, struct ndr_generic_array *nga);");
+                       $self->pidl_fn_start("$dissectorname");
+                       $self->pidl_code("static int");
+                       $self->pidl_code("$cfdissectorname(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, struct ndr_generic_array *nga)");
+                       $self->pidl_code("{");
+                       $self->indent;
+
+                       $self->pidl_code("offset = dissect_ndr_conformant_array_hdr(tvb, offset, pinfo, tree, di, drep, nga);");
+
+                       $self->pidl_code("");
+                       $self->pidl_code("return offset;");
+                       $self->deindent;
+                       $self->pidl_code("}\n");
+               }
+       }
+
        $self->pidl_hdr("int $dissectorname(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, int hf_index _U_, guint32 param _U_);");
 
        $self->pidl_fn_start($dissectorname);
@@ -789,6 +836,11 @@ sub Struct($$$$)
        $self->pidl_code("int old_offset;");
        $self->pidl_code("");
 
+       if (defined $cfdissectorname) {
+               $self->pidl_code("offset = $cfdissectorname(tvb, offset, pinfo, parent_tree, di, drep, &$cfvarname);");
+               $self->pidl_code("");
+       }
+
        if (defined($doalign)) {
                if ($doalign == 1) {
                        $self->pidl_code("ALIGN_TO_$e->{ALIGN}_BYTES;");