⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.pm

📁 wireshark 0.99.7 最新源码
💻 PM
📖 第 1 页 / 共 5 页
字号:
		if (ref($l->{DATA_TYPE}) eq "HASH") {			$t = "$l->{DATA_TYPE}->{TYPE}_$l->{DATA_TYPE}->{NAME}";		} else {			$t = $l->{DATA_TYPE};		}						# strings are passed by value rather than reference		if (not Parse::Pidl::Typelist::is_scalar($t) or 			Parse::Pidl::Typelist::scalar_is_reference($t)) {			$var_name = get_pointer_to($var_name);		}		my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred);		$self->pidl("NDR_CHECK(ndr_push_$t($ndr, $ndr_flags, $var_name));");	} else {		$self->ParseTypePush($l->{DATA_TYPE}, $var_name, $primitives, $deferred);	}}sub CalcNdrFlags($$$){	my ($l,$primitives,$deferred) = @_;	my $scalars = 0;	my $buffers = 0;	# Add NDR_SCALARS if this one is deferred 	# and deferreds may be pushed	$scalars = 1 if ($l->{IS_DEFERRED} and $deferred);	# Add NDR_SCALARS if this one is not deferred and 	# primitives may be pushed	$scalars = 1 if (!$l->{IS_DEFERRED} and $primitives);		# Add NDR_BUFFERS if this one contains deferred stuff	# and deferreds may be pushed	$buffers = 1 if ($l->{CONTAINS_DEFERRED} and $deferred);	return "NDR_SCALARS|NDR_BUFFERS" if ($scalars and $buffers);	return "NDR_SCALARS" if ($scalars);	return "NDR_BUFFERS" if ($buffers);	return undef;}sub ParseMemCtxPullStart($$$$){	my ($self, $e, $l, $ptr_name) = @_;	my $mem_r_ctx = "_mem_save_$e->{NAME}_$l->{LEVEL_INDEX}";	my $mem_c_ctx = $ptr_name;	my $mem_c_flags = "0";	return if ($l->{TYPE} eq "ARRAY" and $l->{IS_FIXED});	if (($l->{TYPE} eq "POINTER") and ($l->{POINTER_TYPE} eq "ref")) {		my $nl = GetNextLevel($e, $l);		my $next_is_array = ($nl->{TYPE} eq "ARRAY");		my $next_is_string = (($nl->{TYPE} eq "DATA") and 					($nl->{DATA_TYPE} eq "string"));		if ($next_is_array or $next_is_string) {			return;		} else {			$mem_c_flags = "LIBNDR_FLAG_REF_ALLOC";		}	}	$self->pidl("$mem_r_ctx = NDR_PULL_GET_MEM_CTX(ndr);");	$self->pidl("NDR_PULL_SET_MEM_CTX(ndr, $mem_c_ctx, $mem_c_flags);");}sub ParseMemCtxPullEnd($$$){	my ($self, $e, $l) = @_;	my $mem_r_ctx = "_mem_save_$e->{NAME}_$l->{LEVEL_INDEX}";	my $mem_r_flags = "0";	return if ($l->{TYPE} eq "ARRAY" and $l->{IS_FIXED});	if (($l->{TYPE} eq "POINTER") and ($l->{POINTER_TYPE} eq "ref")) {		my $nl = GetNextLevel($e, $l);		my $next_is_array = ($nl->{TYPE} eq "ARRAY");		my $next_is_string = (($nl->{TYPE} eq "DATA") and 					($nl->{DATA_TYPE} eq "string"));		if ($next_is_array or $next_is_string) {			return;		} else {			$mem_r_flags = "LIBNDR_FLAG_REF_ALLOC";		}	}	$self->pidl("NDR_PULL_SET_MEM_CTX(ndr, $mem_r_ctx, $mem_r_flags);");}sub CheckStringTerminator($$$$$){	my ($self,$ndr,$e,$l,$length) = @_;	my $nl = GetNextLevel($e, $l);	# Make sure last element is zero!	$self->pidl("NDR_CHECK(ndr_check_string_terminator($ndr, $length, sizeof($nl->{DATA_TYPE}_t)));");}sub ParseElementPullLevel{	my($self,$e,$l,$ndr,$var_name,$env,$primitives,$deferred) = @_;	my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred);	if ($l->{TYPE} eq "ARRAY" and ($l->{IS_VARYING} or $l->{IS_CONFORMANT})) {		$var_name = get_pointer_to($var_name);	}	# Only pull something if there's actually something to be pulled	if (defined($ndr_flags)) {		if ($l->{TYPE} eq "SUBCONTEXT") {			my $subndr = $self->ParseSubcontextPullStart($e, $l, $ndr, $env);			$self->ParseElementPullLevel($e, GetNextLevel($e,$l), $subndr, $var_name, $env, 1, 1);			$self->ParseSubcontextPullEnd($e, $l, $ndr, $env);		} elsif ($l->{TYPE} eq "ARRAY") {			my $length = $self->ParseArrayPullHeader($e, $l, $ndr, $var_name, $env);			my $nl = GetNextLevel($e, $l);			if (is_charset_array($e,$l)) {				if ($l->{IS_ZERO_TERMINATED}) {					$self->CheckStringTerminator($ndr, $e, $l, $length);				}				$self->pidl("NDR_CHECK(ndr_pull_charset($ndr, $ndr_flags, ".get_pointer_to($var_name).", $length, sizeof(" . mapTypeName($nl->{DATA_TYPE}) . "), CH_$e->{PROPERTIES}->{charset}));");				return;			} elsif (has_fast_array($e, $l)) {				if ($l->{IS_ZERO_TERMINATED}) {					$self->CheckStringTerminator($ndr,$e,$l,$length);				}				$self->pidl("NDR_CHECK(ndr_pull_array_$nl->{DATA_TYPE}($ndr, $ndr_flags, $var_name, $length));");				return;			}		} elsif ($l->{TYPE} eq "POINTER") {			$self->ParsePtrPull($e, $l, $ndr, $var_name);		} elsif ($l->{TYPE} eq "SWITCH") {			$self->ParseSwitchPull($e, $l, $ndr, $var_name, $env);		} elsif ($l->{TYPE} eq "DATA") {			$self->ParseDataPull($e, $l, $ndr, $var_name, $primitives, $deferred);		}	}	# add additional constructions	if ($l->{TYPE} eq "POINTER" and $deferred) {		if ($l->{POINTER_TYPE} ne "ref") {			$self->pidl("if ($var_name) {");			$self->indent;			if ($l->{POINTER_TYPE} eq "relative") {				$self->pidl("uint32_t _relative_save_offset;");				$self->pidl("_relative_save_offset = ndr->offset;");				$self->pidl("NDR_CHECK(ndr_pull_relative_ptr2(ndr, $var_name));");			}		}		$self->ParseMemCtxPullStart($e, $l, $var_name);		$var_name = get_value_of($var_name);		$self->ParseElementPullLevel($e, GetNextLevel($e,$l), $ndr, $var_name, $env, 1, 1);		$self->ParseMemCtxPullEnd($e,$l);		if ($l->{POINTER_TYPE} ne "ref") {    			if ($l->{POINTER_TYPE} eq "relative") {				$self->pidl("ndr->offset = _relative_save_offset;");			}			$self->deindent;			$self->pidl("}");		}	} elsif ($l->{TYPE} eq "ARRAY" and 			not has_fast_array($e,$l) and not is_charset_array($e, $l)) {		my $length = ParseExpr($l->{LENGTH_IS}, $env, $e->{ORIGINAL});		my $counter = "cntr_$e->{NAME}_$l->{LEVEL_INDEX}";		my $array_name = $var_name;		$var_name = $var_name . "[$counter]";		$self->ParseMemCtxPullStart($e, $l, $array_name);		if (($primitives and not $l->{IS_DEFERRED}) or ($deferred and $l->{IS_DEFERRED})) {			my $nl = GetNextLevel($e,$l);			if ($l->{IS_ZERO_TERMINATED}) {				$self->CheckStringTerminator($ndr,$e,$l,$length);			}			$self->pidl("for ($counter = 0; $counter < $length; $counter++) {");			$self->indent;			$self->ParseElementPullLevel($e, $nl, $ndr, $var_name, $env, 1, 0);			$self->deindent;			$self->pidl("}");		}		if ($deferred and ContainsDeferred($e, $l)) {			$self->pidl("for ($counter = 0; $counter < $length; $counter++) {");			$self->indent;			$self->ParseElementPullLevel($e,GetNextLevel($e,$l), $ndr, $var_name, $env, 0, 1);			$self->deindent;			$self->pidl("}");		}		$self->ParseMemCtxPullEnd($e, $l);	} elsif ($l->{TYPE} eq "SWITCH") {		$self->ParseElementPullLevel($e, GetNextLevel($e,$l), $ndr, $var_name, $env, $primitives, $deferred);	}}###################################################################### parse scalars in a structure element - pull sizesub ParseElementPull($$$$$$){	my($self,$e,$ndr,$env,$primitives,$deferred) = @_;	my $var_name = $env->{$e->{NAME}};	my $represent_name;	my $transmit_name;	return unless $primitives or ($deferred and ContainsDeferred($e, $e->{LEVELS}[0]));	if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) {		$self->pidl("{");		$self->indent;		$represent_name = $var_name;		$transmit_name = "_transmit_$e->{NAME}";		$var_name = $transmit_name;		$self->pidl(mapTypeName($e->{TYPE})." $var_name;");	}	$var_name = append_prefix($e, $var_name);	$self->start_flags($e);	$self->ParseElementPullLevel($e,$e->{LEVELS}[0],$ndr,$var_name,$env,$primitives,$deferred);	$self->end_flags($e);	# Representation type is different from transmit_as	if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) {		$self->pidl("NDR_CHECK(ndr_$e->{TYPE}_to_$e->{REPRESENTATION_TYPE}($transmit_name, ".get_pointer_to($represent_name)."));");		$self->deindent;		$self->pidl("}");	}}###################################################################### parse a pointer in a struct element or functionsub ParsePtrPull($$$$$){	my($self, $e,$l,$ndr,$var_name) = @_;	my $nl = GetNextLevel($e, $l);	my $next_is_array = ($nl->{TYPE} eq "ARRAY");	my $next_is_string = (($nl->{TYPE} eq "DATA") and 						 ($nl->{DATA_TYPE} eq "string"));	if ($l->{POINTER_TYPE} eq "ref") {		if ($l->{LEVEL} eq "EMBEDDED") {			$self->pidl("NDR_CHECK(ndr_pull_ref_ptr($ndr, &_ptr_$e->{NAME}));");		}		if (!$next_is_array and !$next_is_string) {			$self->pidl("if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {");			$self->pidl("\tNDR_PULL_ALLOC($ndr, $var_name);"); 			$self->pidl("}");		}				return;	} elsif (($l->{POINTER_TYPE} eq "unique") or 		 ($l->{POINTER_TYPE} eq "relative") or		 ($l->{POINTER_TYPE} eq "full")) {		$self->pidl("NDR_CHECK(ndr_pull_generic_ptr($ndr, &_ptr_$e->{NAME}));");		$self->pidl("if (_ptr_$e->{NAME}) {");		$self->indent;	} else {		die("Unhandled pointer type $l->{POINTER_TYPE}");	}	# Don't do this for arrays, they're allocated at the actual level 	# of the array	unless ($next_is_array or $next_is_string) { 		$self->pidl("NDR_PULL_ALLOC($ndr, $var_name);"); 	} else {		# FIXME: Yes, this is nasty.		# We allocate an array twice		# - once just to indicate that it's there,		# - then the real allocation...		$self->pidl("NDR_PULL_ALLOC($ndr, $var_name);");	}	#$self->pidl("memset($var_name, 0, sizeof($var_name));");	if ($l->{POINTER_TYPE} eq "relative") {		$self->pidl("NDR_CHECK(ndr_pull_relative_ptr1($ndr, $var_name, _ptr_$e->{NAME}));");	}	$self->deindent;	$self->pidl("} else {");	$self->pidl("\t$var_name = NULL;");	$self->pidl("}");}sub ParseStructPushPrimitives($$$$){	my ($self, $struct, $varname, $env) = @_;	# see if the structure contains a conformant array. If it	# does, then it must be the last element of the structure, and	# we need to push the conformant length early, as it fits on	# the wire before the structure (and even before the structure	# alignment)	if (defined($struct->{SURROUNDING_ELEMENT})) {		my $e = $struct->{SURROUNDING_ELEMENT};		if (defined($e->{LEVELS}[0]) and 			$e->{LEVELS}[0]->{TYPE} eq "ARRAY") {			my $size;						if ($e->{LEVELS}[0]->{IS_ZERO_TERMINATED}) {				if (has_property($e, "charset")) {					$size = "ndr_charset_length($varname->$e->{NAME}, CH_$e->{PROPERTIES}->{charset})";				} else {					$size = "ndr_string_length($varname->$e->{NAME}, sizeof(*$varname->$e->{NAME}))";				}			} else {				$size = ParseExpr($e->{LEVELS}[0]->{SIZE_IS}, $env, $e->{ORIGINAL});			}			$self->pidl("NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, $size));");		} else {			$self->pidl("NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_string_array_size(ndr, $varname->$e->{NAME})));");		}	}	$self->pidl("NDR_CHECK(ndr_push_align(ndr, $struct->{ALIGN}));");	if (defined($struct->{PROPERTIES}{relative_base})) {		# set the current offset as base for relative pointers		# and store it based on the toplevel struct/union		$self->pidl("NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, $varname, ndr->offset));");	}	$self->ParseElementPush($_, "ndr", $env, 1, 0) foreach (@{$struct->{ELEMENTS}});}sub ParseStructPushDeferred($$$){	my ($self, $struct, $varname, $env) = @_;	if (defined($struct->{PROPERTIES}{relative_base})) {		# retrieve the current offset as base for relative pointers		# based on the toplevel struct/union		$self->pidl("NDR_CHECK(ndr_push_setup_relative_base_offset2(ndr, $varname));");	}	$self->ParseElementPush($_, "ndr", $env, 0, 1) foreach (@{$struct->{ELEMENTS}});}###################################################################### parse a structsub ParseStructPush($$$){	my ($self, $struct, $varname) = @_;		return unless defined($struct->{ELEMENTS});	my $env = GenerateStructEnv($struct, $varname);	EnvSubstituteValue($env, $struct);	$self->DeclareArrayVariables($_) foreach (@{$struct->{ELEMENTS}});	$self->start_flags($struct);	$self->pidl("if (ndr_flags & NDR_SCALARS) {");	$self->indent;	$self->ParseStructPushPrimitives($struct, $varname, $env);	$self->deindent;	$self->pidl("}");	$self->pidl("if (ndr_flags & NDR_BUFFERS) {");	$self->indent;	$self->ParseStructPushDeferred($struct, $varname, $env);	$self->deindent;	$self->pidl("}");	$self->end_flags($struct);}###################################################################### generate a push function for an enumsub ParseEnumPush($$$){	my($self,$enum,$varname) = @_;	my($type_fn) = $enum->{BASE_TYPE};	$self->start_flags($enum);	$self->pidl("NDR_CHECK(ndr_push_$type_fn(ndr, NDR_SCALARS, $varname));");	$self->end_flags($enum);}###################################################################### generate a pull function for an enumsub ParseEnumPull($$$){	my($self,$enum,$varname) = @_;	my($type_fn) = $enum->{BASE_TYPE};	my($type_v_decl) = mapTypeName($type_fn);	$self->pidl("$type_v_decl v;");	$self->start_flags($enum);	$self->pidl("NDR_CHECK(ndr_pull_$type_fn(ndr, NDR_SCALARS, &v));");	$self->pidl("*$varname = v;");	$self->end_flags($enum);}###################################################################### generate a print function for an enumsub ParseEnumPrint($$$$){	my($self,$enum,$name,$varname) = @_;	$self->pidl("const char *val = NULL;");	$self->pidl("");	$self->start_flags($enum);	$self->pidl("switch ($varname) {");	$self->indent;	my $els = \@{$enum->{ELEMENTS}};	foreach my $i (0 .. $#{$els}) {		my $e = ${$els}[$i];		chomp $e;		if ($e =~ /^(.*)=/) {			$e = $1;		}		$self->pidl("case $e: val = \"$e\"; break;");	}	$self->deindent;	$self->pidl("}");		$self->pidl("ndr_print_enum(ndr, name, \"$enum->{TYPE}\", val, $varname);");	$self->end_flags($enum);}sub DeclEnum($$$$){	my ($e,$t,$name,$varname) = @_;	return "enum $name " . 		($t eq "pull"?"*":"") . $varname;}$typefamily{ENUM} = {	DECL => \&DeclEnum,	PUSH_FN_BODY => \&ParseEnumPush,	PULL_FN_BODY => \&ParseEnumPull,	PRINT_FN_BODY => \&ParseEnumPrint,};###################################################################### generate a push function for a bitmapsub ParseBitmapPush($$$){	my($self,$bitmap,$varname) = @_;	my($type_fn) = $bitmap->{BASE_TYPE};	$self->start_flags($bitmap);	$self->pidl("NDR_CHECK(ndr_push_$type_fn(ndr, NDR_SCALARS, $varname));");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -