{	*******************************************************

	Include file of standard domain constants and types

	******************************************************* }

const	
	dns_socket=53;		{ socket for domain server }
	test_version=false;	{ If true, use dns_socket + 100,
				  test files, etc }

	dbvern=17;		{ internal version number be sure to
				  change version whenever you make *any*
				  changes to structure of database }

	abort=true;		{ 1st arg to jsys_err }
	noabort=false;

	jsys_test=true;		{ should the jsys test be used ? }
	no_jsys_test=false;
	cr=13;			{ carriage return / line delimiter }
	lf=10;			{ line feed }
	tab=9;			{ tab character }

	ip_hdr_sz=20;		{ octets in the IP header }
	udp_hdr_sz=8;		{ octets in the UDP header }
	dmn_hdr_sz=12;		{ octets in the domain style header }
	max_dgm_octets=548;	{ max datagram octets }
	max_msg_octet=64000;	{ max size uncompressed message }

	max_atom_chars=15;	{ max characters in a syntactic
				  atom, e.g. in master file }
	max_big_atom_chars=80;	{ max chars in a big atom }
	max_binary_octets=40;	{ max binary octets in a chunk }
	max_chunk=10;		{ max chunks per RDATA }
	max_dname_chars=256;	{ max octets in a dname }
	max_dname_labels=128;	{ max labels in a dname }
	max_exp_rrs=15;		{ max number of exp RRs in a section }
	max_fn_chars=63;	{ max characters in a filename }
	max_int_rrs=50;		{ max number of int RRs in a section }
	max_rrs=200;		{ max RRs in a section }
	max_lab_chars=63;	{ max octets in a label }
	max_lab_levels=20;	{ max levels in a label }
	max_rdata_items=8;	{ max fields in an rdata_entry }

	max_search_servers=4;   { max servers per request }
	max_server_addresses=3;	{ max addresses per server }

	max_zlhosts=3;		{ maximum number of hosts which can be
				  used to refresh a particular network
				  loaded zone }

	tslots=200;		{ max time slots in tgraph }
	hslots=200;		{ max host slots in graph }
	qslots=256;		{ max qtype slots in qgraph }
	cslots=256;		{ max qclass slots in cgraph }
	dimax=143;		{ time of day interval max (10 min interval) }
	sgmax=10;		{ maximum section count in size graph }
	prfmax=12;		{ maximum array index of address preference }
	maxcs=512;		{ maximum compression savings to graph }

	label_hashmod=1009;	{ modulo for label hashing }
	label_hashmax=1008;	{ label_hashmod-1 }

	{ message opcodes }
	std_query=0;		{ standard query }
	inv_query=1;		{ inverse query }
	cm_query=2;		{ completion query--multiple answers }
	cu_query=3;		{ completion query--unique answer }

	{ response codes  }
	no_error=0;		{ no error }
	format_error=1;		{ NS couldn't interpret query }
	server_failure=2;	{ problem with NS }
	name_error=3;		{ domain name doesn't exist }
	not_implemented=4;	{ no support for this query type }
	refused=5;		{ NS refused for policy reasons }

	{ qtype special values }
	axfr=252;		{ transfer entire zone }
	mailb=253;		{ mailbox related RRs: mb, mg, mr }
	maila=254;		{ mail agent RRs: md, mf }

	star=255;		{ qtype and qclass wildcard }	

type	
	atom=packed array[1..max_atom_chars] of char;
	big_atom=packed array[1..max_big_atom_chars] of char;
	filename=packed array[1..max_fn_chars] of char;

	itime=integer;		{ internal times are seconds, either
				  positive delta or negative absolute }

	lock=	record
		lockwd:integer;		{ master lock }
		share:integer;		{ share count }
		exclusive:integer	{ exclusive count }
		end;

	dname_string=packed array[1..max_dname_chars] of octet;

	dname_string_table=record
		count:0..max_dname_labels;
		bp:array[1..max_dname_labels] of g1bpt
		end;

	dtype=( dtype_l_bound,	{ lower bound is not valid }
		a,		{ host address }
		ns,		{ authoritative name server }
		md,		{ mail destination }
		mf,		{ mail forwarder }
		cname,		{ canonical name }
		soa,		{ start of zone of authority }
		mb,		{ mailbox domain name }
		mg,		{ mail group member }
		mr,		{ mail rename }
		null,		{ null RR }
		wks,		{ well known service description }
		ptr,		{ domain name pointer }
		hinfo,		{ host information }
		minfo,		{ mailbox or mail list information }
		mx,		{ mail agent replacement for MD + MF }
		dtype_h_bound );{upper bound is not valid }
		
	qtype=0..177777b;	{ qtypes include dtype plus those
				  defined above }

	dclass=( dclass_l_bound,  { lower bound is not valid }
		 internet,	  { ARPA Internet }
		 csnet,		  { CSNET }
		 dclass_h_bound );{ upper bounnd is not valid }

	qclass=0..177777b;	{ qclass includes dclass plus star }

	sectcode=(question,answer,authority,additional);

	{ ***** Storage allocation types ***** }

	satype=(sd_slt,		{ storage allocation types }
		sd_zone,
		sd_ulabel,
		sd_dname,
		sd_node,
		sd_lht,
		sd_rr,
		sd_rdchunk,
		sd_litstring);

	sakind=(sa_units	{ record number of allocations }
		,sa_aus		{ record number of AUs allocated }
		);

	sapool=(sa_search	{ allocations for search related items }
		,sa_data	{ allocations for data }
		);

	stgmap=array[satype,sakind] of integer;

        pagemap=packed array[db_first_page..db_last_page] of boolean;

	free_block=record
		next:free_block_pointer;{ next free block }
		size:integer		{ number of free AUs in block }
	    end;
	
	{ ***** RDATA format types *****

	  These types are used with the IRDATA routine to describe
	  the structure of the RDATA fields for a given type and class 
	}

	rdata_field=( dname_field,	{ domain name }
		      cstring_field,	{ string, e.g. CPU in HINFO }
		      time_field,	{ 32 bit time value }
		      int16_field,	{ 16 bit integer }
		      int32_field,	{ 32 bit integer }
		      inet_a_field,	{ 32 bit IP address }
		      inet_p_field,	{ 8 bit IP protocol number }
		      inet_s_field,	{ variable length IP socket WKS }
		      vbinary_field,	{ variable length binary field }
		      no_more_field );	{ end marker for table }

	rdata_entry=packed record
	       rdata_item:packed array[1..max_rdata_items] of rdata_field;
	       rdata_asp:packed array[1..max_rdata_items] of qtype
			   end;
	
	rdata_table=packed array[dtype] of rdata_entry;

	{ ***** label definitions *****

	  Labels are managed separately for each zone.
	  Each zone has a label table that points to the unique 
	  definitions for each distinct label, where distinct 
	  is case-insensitive, i.e. there is a single unique
	  label (ULABEL) for all occurances of "A" or "a" in a
	  particular zone.  The purpose of this is to allow us
	  to find all occurances of the use of a label in nodenames,
	  and to make label references fixed in size.

	  ULABELs are in UPPER CASE.

	  An instance of a label in the database is represented 
	  using a ULABEL pointer and an array of modifier bits 
	  in a mod_bits.  Modifier bits are associated one-to-one
	  with octets in a ULABEL, and signify characters that
	  should be mapped to lower case when the data is exported.
	  This can be done by adding octal 40 to an octet.

	  Nodes that have the same label are chained together.  
}
	

	{ in label_string, octet zero is length }
	label_string=packed array[0..max_lab_chars] of octet;

	ulabel= record
		nodeptr:node_pointer;	{ node with this label }
		next:ulabel_pointer;	{ ptr to next label }
		text:label_string
		end;
	
	mod_bits=packed array[1..max_lab_chars] of boolean;

	lab_use=record
		    labptr:ulabel_pointer;
		    case_mod:mod_bits
		end;
	
	{ these data structures used to locate ULABELS }

	secondary_label_table=record
				  direct:ulabel_pointer;
				  lchain:array[octet] of ulabel_pointer
			      end;
	
	primary_label_table=record
				direct:ulabel_pointer;
				stable:array[octet] of secondary_label_table_pointer
			    end;
	
	{ these data structures used for nodes and dnames }

	label_hashrange=0..label_hashmax;
	label_hashtable=record
			case boolean of
			true:	(node_hash:array[label_hashrange] of node_pointer);
			false:	(dname_hash:array[label_hashrange] of dname_pointer)
			end;

	{ ***** domain name definitions *****

	  Like labels, there is a single representation for a
	  particular domain name in a particular zone.  Unlike
	  labels, domain names are not case insensitive.  That
	  is, while all occurances of ISI.ARPA will use the same
	  data via multiple pointers, isi.ARPA will be a different
	  representation from ISI.ARPA.  Thus to test to see if 
	  two domain names in a zone are the same, it is necessary 
	  to see if they are the same length and if all their
	  corresponding ULABEL pointers are EQ.  Note that the 
	  purpose here is to reduce storage requirements, rather
	  than achieve any sort of accessing.

	  A domain name, say X1.X2 is represented as a linked list
	  with three DNAME blocks:

  	  +----------+          +----------+          +----------+
	  |          |--------->|          |--------->|    nil   |
	  +----------+          +----------+          +----------+
	  |          |          |          |          |          |
	  +-----|----+          +-----|----+          +-----|----+
	        |                     |                     |
	        V                     V                     V
	  ULABEL of X1          ULABEL of X2          ULABEL of ""(root)

	  All domain names of length Y are chained off of the hash
	  table pointed to by the Yth entry in dname_table.  Domain
	  names of length N+1 will point to a domain name of length N,
	  which is chained from the Nth entry in dname_table.
	}

	dname=record
		  dlabel:lab_use;	
		  more:dname_pointer;		{ following labels in name }
		  dname_chain:dname_pointer	{ next name of this size }
	      end;
	
	dname_table=array[1..255] of label_hashtable_pointer;

	{ ***** node definitions *****

	  The structure of a domain tree in a zone is composed
	  of chained NODE blocks.

	  Each node block has a pointer (UP_PTR) to its direct 
	  ancestor, a pointer (SIDE_PTR) to its next sibling,
	  and a pointer (DOWN_PTR) to its first sibling.  All 
	  nodes with a particular direct ancestor are chained 
	  together in alphabetical order of node name via 
	  SIDE_PTRs.  No two siblings can have labels that are
	  identical except for case; the first casing into the
          database stays.  That is, while we may have nodes 
	  X.ARPA and x.CSNET, we can't have x.ARPA and X.ARPA.

	  All nodes which refer to the same ULABEL are chained
	  together via node_lchain.

	  Nodes with a high branching factor for children may
	  have a non NIL entry in DOWN_TBL.  The Nth entry in
	  the DOWN_TBL points to the first child which starts 
	  with the specified octet.
	
	The variant record part of the node record is always rr_ptr
	except for the search zone. }

	node=record
		node_label:lab_use;
		node_lchain:node_pointer; { next node with same label }
		up_ptr:node_pointer;
		side_ptr:node_pointer;
		down_ptr:node_pointer;
		down_tbl:label_hashtable_pointer;
		case boolean of
		true:	(rr_ptr:rr_pointer);
		false:	(zone_ptr:zone_entry_pointer)
	     end;
	
	{ ***** RR definitions *****

	  Each RR is represented as a RR block with a chain of
	  rdchunks that make up the RDATA field.

	  All RRs of a particular type and class are chained 
	  together via RDCHAIN.  These chains are anchored in
	  the zone's RR_TABLE array.  These chains are used in
	  inverse queries.

	  The RDATA field of an RR is represented as a linked list
          of RDCHUNKs.  RDCHUNKS contain either a doamin name or
          literal data.
	}

	rr=packed record
		 next:rr_pointer;	{ pointer to next RR this node }
		 ttl:integer;		{ expiration time }
		 rrtype:dtype;		{ resource record type }
		 rrclass:dclass;	{ resource record class }
		 rdata:rdchunk_pointer;	{ pointer to first RR chunk }
	   end;

	rr_table=array[dtype,dclass] of rr_pointer;

	chunktypes=( lit_chunk, name_chunk );

	litstring=packed record
			case boolean of
			true:	(lcount:field16);
		      	false:	(ldata:packed array[-1..max_binary_octets] of octet)
		  end;
	
	rdchunk=record
		    more:rdchunk_pointer;    {ptr to more of this RDATA}
		    rdchain:rdchunk_pointer; {ptr to next chunk at this level}
		    case ckind:chunktypes of
			lit_chunk:	( litdata:litstring_pointer );
			name_chunk:	( rrname:dname_pointer )
		    end;
		    
	rd_table=array[1..max_chunk,0..255] of rdchunk_pointer;

{	*******************************************************

	Expanded domain types

	******************************************************* }

	exp_label=packed record
			     labinfo:label_string;
			     case_mod:mod_bits
			 end;
			 
	exp_dname=packed record
			     count:0..max_lab_levels;	{ number of labels }
			     dlabels:array[1..max_lab_levels] of exp_label
			 end;
	
	exp_chunk=packed record
	     case ckind:chunktypes of
		  lit_chunk:(lit_data_count:0..max_binary_octets;
			     lit_data:packed array[1..max_binary_octets]
					     of octet);
		  name_chunk:(rrname:exp_dname)
	     end;
	     
	exp_rr=record
		   ttl:integer;
		   rrtype:dtype;
		   rrclass:dclass;
		   chunk_count:integer;
		   chunks:array[1..max_chunk] of exp_chunk
	       end;
	
	{ zone definitions }

	zone_ltype=(zloadf,	{ zone loaded from file }
		   zloadfd,	{ zone from file with file date as serial }
		   cloadf,	{ cache load from file }
		   zloadn	{ zone loaded over network }
		);

	zone_cdata=record	{ refresh configuration for zone }
		zone_to_load:exp_dname;
		zone_uses_filedates:boolean;
		zone_serial:integer;
		zone_refresh:integer;
		zone_retry:integer;
		zone_expire:integer;
		zone_minimum:integer;
		loadclass:dclass;
		default_rinterval:integer;
		case loadtype:zone_ltype of

		zloadf,
		zloadfd:	(refresh_file:filename);

		zloadn:		(hostcount:0..max_zlhosts;
				 hosts:array[1..max_zlhosts] of exp_dname)

		end;

	file_type = ( fatl, err, log );

	file_blk = record
			flock:lock;		  
			fident:file of char;
		   end;
	
	zone_entry=record
		zone_chain:zone_entry_pointer;	{ next authoritative }
		zone_node:node_pointer; {ptr to zone's root node}
		zone_class:dclass;
		loaded:boolean;
		zsoa:node_pointer;	{ptr to node with SOA}
		zsoa_rr:rr_pointer;	{ SOA record for zone }
		zone_is_cache:boolean;
		zone_lock:lock;
		zone_config:zone_cdata;
		dtable:dname_table;
		ltable:primary_label_table;
{		rrtable:rr_table;	}
		rdtable:rd_table;
		sadata:stgmap;		{ storage allocation statistics }
	        zone_pools:array[sapool] of free_block_pointer;
		zone_pages:pagemap
		end;
		       
	search_block=record
		slock:integer;	{ AOSE lockword for this block }
		sbnext:search_block_pointer;
		rcomp:integer_pointer;	{pointer to resolver command}
		ldores:integer;	{non-zero if reserved for ldo}
		erttl:integer;	{recursion counter to kill infinite loops}
		tstart:integer;	{MSclock when query was started}
		tquery:integer;	{absolute time query was started}
		fcode:integer;
		psave:integer;	{ jsys save area for stack pointer }
		sname:dname_string;
		stable:dname_string_table;
		stype:qtype;
		sclass:qclass;
		lock1:lock_pointer;	{ pointers to locked zones }
		lock2:lock_pointer;
		locked:integer;
		azone:zone_entry_pointer;
		alabel:integer;
		lmatch:integer;
		derc:integer;
		outcnt:integer;
		outins:integer;
		outbp:integer;
		cnptr:integer;
		anret:integer;
		adpref:integer;
		adeln:node_pointer;	{node pointer for authoritative delegation}
		adell:integer;		{label value from jsys}
		cdeln:node_pointer;	{node pointer for cache delegation}
		cdell:integer;		{label value from jsys}
		dnbp:integer;	
		dncp:integer;
		dnlc:integer;

		rtimeo:integer;		{time of next activity}
		resttl:integer;		{watchdog inside resolver}
		rflags:integer;		{flags register from JSYS code}
		rsolvn:node_pointer	{node where resolver placed answers}
		end;

	hgraph_index=1..hslots;

	hgraph_type=record
		host:integer;		{ host address }
		touts:integer;		{ times started }
		tbacks:integer;		{ times completed }
		ttotal:integer		{ total delay for responses }
		end;

	hgraph=array[hgraph_index] of hgraph_type;

	tgraph=record			{ timing graph }	
		touts:integer;		{ times started }
		tbacks:integer;		{ times completed }
		ttotal:integer;		{ total delay for responses }
		tquanta:integer;	{ slot spacing}
		tdelay:array[0..tslots] of integer; { histogram by tquanta }
		end;

	qgraph_index=1..qslots;
	qgraph=array[qgraph_index] of integer;	{ graph usage by qtype,
						  last slot is other }

	cgraph_index=1..cslots;
	cgraph=array[cgraph_index] of integer;	{ graph usage by qclass,
						  last slot is other }

	sgraph=record
		strun:integer;		{ truncations in this section }
		ssize:array[0..sgmax] of integer
		end;

	search_address_type=record
		tries:integer;		{ transmissions made }
		limit:integer;		{ transmissions remaining }
		ipaddress:integer;
		stat_ptr:integer;	{ index in hgraph for RT }
		eta:integer;		{ estimated RTT in milliseconds }
		rank:integer;		{ comparitive worth of server }
	    end;

	server_type=record
		server_name:dname_string; (* name of server *)
		addresses_ready:boolean; (* address setup done? *)
		address_count:integer; (* number of addresses *)
		server_addresses:array[1..max_server_addresses] of search_address_type;
	    end;

	servers_dv=record
		server_count:integer; { count of server references }
		server_quality:integer; { how good is this delegation }
		server_at:dname_string; { name of delegated zone }
		server_at_len:integer; { length of server_at }
		servers:array[1..max_search_servers] of server_type;
		end;

	fruse=record	{ fork resource usage }
		elpgt:integer;		{ elapsed page traps }
		elpgf:integer;		{ elapsed page faults }
		elpgrt:integer;		{ elapsed time in paging code (ms)}
		elrun:integer;		{ elapsed runtime (ms) }
		elwall:integer;		{ elapsed wallclock time (ms) }
		elwb:integer;		{ elapsed base (process start time ) }
		end;

	msure_type=record
		mname:dname_string;	{ Name of measured host }
		mcomment:packed array[1..100] of char; { measurement comment }
		mclear:integer;		{ GTAD time of statistics reset }
		mdate:integer;		{ GTAD time of measurement }
		tzero:integer;		{ GTAD time of database creation }
		prifn:filename;		{ Filename of primary database }
		secfn:filename;
		dupver:integer;		{ version number duplicate }
		infttl:integer;		{ limit for JSYS looping }
		plttl:integer;		{ primitive lock disms time in MS }
		lckttl:integer;		{ MS wait for exclusive to clear }
		rwaiti:integer;		{ initial MS wait for resolver }
		rwait:integer;		{ subsequent MS wait for resolver }
		ripoll:integer;		{ resolver idle poll interval }
		rbpoll:integer;		{ resolver busy poll interval }
		qtoi:integer;		{ query initial timeout }
		qtor:integer;		{ query retransmission timeout }
		qtoq:integer;		{ query timeout for quiet interval }

		dynsw:integer;		{ non-zero for RTT timeouts }
		dynnum:integer;		{ numerator of ETA to timeout ratio }
		dynden:integer;		{ denominator }

		prefm:array[0..prfmax] of integer; { preference masks }
		prefv:array[0..prfmax] of integer; { preference values }
		prefe:array[0..prfmax] of integer; { preference ETA }

		rmttl:integer;		{ resolver max TTL }
		maxit:integer;		{ max individual address tries }
		maxst:integer;		{ max tries per server }

		dcalls:integer;		{ calls to GTDOM% }
		dbyfn:array [0..gtdfmx] of integer; {GTDOM% calls by function}
		dbyqt:qgraph;		{ GTDOM% calls by QTYPE}
		dscall:integer;		{ calls to DSETUP }
		dsbbsy:integer;		{ busy SBLOCKS found in DSETUP }
		dsbbl:integer;		{ all SBLOCKS busy }
		dedoa:integer;		{ finite effort requests killed }
		daztry:integer;		{ authoritative zone to search }
		dazne:integer;		{ name error in authoritative }
		dazdel:integer;		{ authoritative delegation }
		dazstr:integer;		{ authoritative * node }
		dazfnd:integer;		{ authoritative node used }
		dcache:integer;		{ attempts to use cache }
		dcnmba:integer;		{ cache uses allowed by MBA }
		dcans:integer;		{ cache found answers }
		dresol:integer;		{ attempts to use resolver }
		drnldo:integer;		{ resolve uses allowed by LDO }
		drrip:integer;		{ resolves left going in background }
		drdism:integer;		{ DISMS in rsolve }
		dcncal:integer;		{ CNAMEL calls }
		dcngo:integer;		{ times CNAMEL infchk OK }
		dicdie:integer;		{ infinite loop check failures }
		dpwait:integer;		{ times waited on primitive lock }
		dewait:integer;		{ times waited for excusive to leave }
		dferr:integer;		{ DFINIS with error }
		dfok:integer;		{ DFINIS without error }
		dfgra:tgraph;		{ DFINIS time graph }
 
		uierrs:integer;		{ UDP input errors }
		uoerrs:integer; 	{ UDP output errors }

		udpgra:tgraph;		{ UDP delay tabulation }
		udphst:hgraph;		{ UDP host response graph }
		newudp:hgraph;		{ recent data used for strategy }
		udphl:integer;		{ NEWUDP halflife in ms }
		udpdcy:integer;		{ time for next halflife decay }
		rusage:fruse;		{ resolver resource usage }
		resolve_loops:integer;	{ times resolver loop executed }

		nsugra:tgraph;		{ Name server response time graph }
		nsuhst:hgraph;		{ Name server host graph }
		nsucod:array[field4] of integer; { NS requests by response }
		nsbyqt:qgraph;		{ NS requests by QTYPE }
		nsbyqc:cgraph;		{ NS requests by QCLASS }
		bogon:integer;		{ NS incomming BOGONS }
		pfail:integer;		{ arriving parse failures }
		nsbyds:array[0..dimax] of integer; { time of day graph }
		nusage:fruse;		{ name server resource usage }
		nsaa:integer;		{ authoritative answer count }
		nudptc:integer;		{ UDP caused truncation }
		nssgra:array[sectcode] of sgraph; { section statistics}
		nsusiz:array[0..512] of integer; {response size graph}
		nsucs:array[0..maxcs] of integer { compression savings }
		end;

	{ ***** master block ***** }

	master_block=record
		dirty:integer;		{ MUST BE FIRST- see cpymaster }
		update_lock:lock;	{ lock for all updating }
		dflush:integer;		{ non-zero to flush JSYSi }
		zupdate:integer;	{ GTAD of zone  update }
		cupdate:integer;	{ GTAD of cache update }
		jsys_init:integer;	{ zero if not used by JSYS }
		dbvers:integer;		{ internal software version number}
		prijfn:integer;		{ JFN for primary database }
		secjfn:integer;		{ JFN for secondary database }
		master_base:master_block_pointer;
		alloc_lock:lock;	{ lock for allocation }
		used_pages:pagemap;
		search_zone:zone_entry;
		cache_lock:lock;	{ lock for discarding cache }
		cache_pointer:zone_entry_pointer;
		msg_files:array[file_type] of file_blk;
		sbloop:search_block_pointer;
		rcom:array[1..max_sb] of integer;
		iaorg:dname_string;
		starbp:g1bpt;		{ g1bpt to '*' }
		stard:packed array[1..4] of octet;	{ * }
		sb_array:array[1..max_sb] of search_block;
		resolve_handle:integer;	{ resolver UDP handle }
		resolve_port:integer;	{ resolver port }
		resolve_job:integer;	{ resolver job, -1 if none }
		logrn:integer;	{ non-zero for normal resolver logging }
		logri:integer;	{ non-zero to dump incoming resolver packets }
		logrp:integer;	{ non-zero for all resolver peculiar }
		logns:integer;	{ non-zero for nameserver summary log }
		logue:integer;	{ non-zero to log UDP errors }
		logua:integer;	{ non-zero to log all UDP packets }
		resolve_addrs:server_type; { addresses to resolve from }
		resolve_dserve:servers_dv; { default servers }
		measure:msure_type	{ measurement data }
		end;
	
	qsection=packed record
			    qnames:array[1..max_exp_rrs] of exp_dname;
			    qtypes:packed array[1..max_exp_rrs] of qtype;
			    qclasses:packed array[1..max_exp_rrs] of qclass
			{   qanswer:array [1..max_int_rrs] of rr_pointer 
				deleted 9/13/88 since it seemed stupid PVM }
		end;
	
	exp_ref=packed record
			   aproc:boolean;
			   rr_data:exp_rr;
			   owner:exp_dname;
		       end;
	
	int_ref=packed record
			   aproc:boolean;
			   rr_ptr:rr_pointer;
			   owner_used:boolean;	{ true if owner has name }
			   owner:exp_dname	{ rather than tree location } 
		       end;
	
	section=packed record
			   exp_count:integer;	{ count of exps }
			   exp:array[1..max_exp_rrs] of exp_ref;
			   int_count:integer;	{ count of ints }
			   int:array[1..max_int_rrs] of int_ref;
		       end;
	
	{* Header fields as defined by the RFC.  This form is 
	   used throughout the program in representing the header. *}
	header_template=packed record
			    id:field16;         { identifier for query }
			    response:boolean;	{ query (0) / response (1) }
			    opcode:field4;	{ kind of query }
			    aa:boolean;		{ responding NS is authority }
			    tc:boolean;		{ message was truncated }
			    rd:boolean;		{ recursion desired }
			    ra:boolean;		{ recursion available }
			    unused:field3;	{ fill to 16 }
			    rcode:field4;	{ response code }
			    qdcount:field16;	{ question section count }
			    ancount:field16;	{ answer section count}
			    nscount:field16;	{ authority section count }
			    arcount:field16	{ additional section count }
			end;
	
	{* Data send/receive format *}
	pkt_type=packed record
			    header:header_template;
			    data_recs:packed array[1..536] of octet
			end;
	
	xmit_type=(dgm, tcp); 

	{* Format for queries used by dgm/tcp routines }
	message_template=packed record
				    xmit_using:xmit_type; 
				    octet_cnt:integer;  { in data_recs }
				    to_address:integer;
				    to_port:integer;
				    from_address:integer;
				    from_port:integer;
				    raw_pkt:pkt_type
				end;

	{* Internal representation of query/response *}
	query_template=record
			rawmsg:message_template;
			header:header_template;
			q_section:qsection; 	{question}
			sdata:array[sectcode] of section
			end; { query_template }

{	***** New style message definitions ***** 	}


	chunke_type=record
		bp:g1bpt; (* pointer to data *)
		length:integer; (* length in bytes *)
		kind:chunktypes (* type of chunk *)
		end;

	rdchunk_table=record
		count:0..max_chunk;
		chunke:array[1..max_chunk] of chunke_type;
		end;

	dheader_type=packed record
		domain_id:field16;	        { identifier for query }
		response:boolean;	{ query (0) / response (1) }
		opcode:field4;		{ kind of query }
		aa:boolean;		{ responding NS is authority }
		tc:boolean;		{ message was truncated }
		rd:boolean;		{ recursion desired }
		ra:boolean;		{ recursion available }
		unused:field3;		{ fill to 16 }
		rcode:field4;		{ response code }
		qdcount:field16;	{ question section count }
		ancount:field16;	{ answer section count}
		nscount:field16;	{ authority section count }
		arcount:field16		{ additional section count }
		end;

	rawmsg=	packed record
		rec_count:field18;     {received word count}
		count:field18;         {word count}
		case boolean of
		true:	(unspec:packed array[1..max_msg_octet] of octet);
		false:	(version:field4;        {ip header}
			 ihl:field4;
			 tos:field8;
			 iplength:field16;
			 unused1:field4;
			 ident:field16;
			 flagrsvd:field1;
			 flagdf:field1;
			 flagmf:field1;
			 fragment:field13;
			 unused2:field4;
			 ttl:field8;
			 protocol:field8;
			 ipchecksum:field16;
			 unused3:field4;
			 sorc_adr:field32;
			 unused4:field4;
			 dest_adr:field32;
			 unused5:field4;       {end ip header}
			 sorc_port:field16;    {udp header}
			 dest_port:field16;
			 unused6:field4;
			 udplength:field16;
			 udpchecksum:field16;  {end udp}
			 dhead:dheader_type)
		end;
 
	transport=packed record	{ transport information }
		xmit_using:xmit_type; 
		foreign_address:integer;
		foreign_port:integer;
		local_address:integer;
		local_port:integer
		end;

	rrdv=	record
		namebp:g1bpt;		{ pointer to name }
		databp:g1bpt		{ pointer to data }
		end;

	section_dv=record
		truncated:boolean;
		count:integer;
		rdv:array[1..max_rrs] of rrdv
		end;

	domsg=	packed record		{ domain format message }

		free_ptr:g1bpt;		{ pointer to unused octet }
		free_cnt:integer;	{ count of free octets }
		parse:array[sectcode] of section_dv;

		case boolean of
		true:	(dhead:dheader_type);	{ domain header		}
		false:	(data:packed array[1..max_msg_octet] of octet);
		end.