<?php
/*
$Id: edit_doc.php 579 2014-05-17 21:23:44Z bhockney $
(C) 2003-2014 by Bob Hockney <zeus@ix.netcom.com>

Report editor documentation

This code is distributed under the terms of GNU GPL
*/
?>

<?php 
if (!isset($name)) $name = "{$FWLOG['report']}";
$intro_doc ="
<h2>User's Guide to the Webfwlog Report Editor</h2>
	<h3>Navigation Buttons</h3>
	<dl>
		<dt>Refresh</dt>
			<dd>Press the Refresh button to update the display.  This is useful, for example, if you have added<br>
				or removed columns, or changed their order, and want to see the list updated reflecting the changes.<br>
				You should also do this before running a report if you want to be able to reuse the settings in the<br>
				same session by using the back button to return to the report editor, but do not want to save the<br>
				new settings permanently.</dd>
		<dt>Run Report</dt>
			<dd>Press the Run Report button to run a report using the current settings. You should press the Refresh<br>
				button first if you want any changes to the settings remembered if you use your browser's back button<br>
				button to return to the report editor.</dd>
		<dt>Return to Main Menu</dt>
			<dd>Press the Return to Main Menu button to go to the main menu.</dd>
	</dl>
	<h3><a name=report_help>Report Management</a></h3>
	<dl>
		<dt>Select Report</dt>
			<dd>You can recall the settings for a previously saved report by selecting it from the list and<br>
				pressing the Use Report button.  Any unsaved changes to the current report will be lost.</dd>
		<dt>Status</dt>
			<dd>Status Messages are displayed below the Select Report Control.</dd>
		<dt>Report Code</dt>
			<dd>This is the code of the saved report currently being edited.<br>
				If the report has not yet been saved it will show as &quot;&lt;NEW>&quot;<br>
				If an imported report has not been saved it will show as &quot;&lt;name_of_imported_file>&quot;</dd>
		<dt>Description</dt>
			<dd>This is a description of the current report and will be displayed on the main menu.<br>
				It will be saved with the report definition.</dd>
		<dt>Save</dt>
			<dd>Press the Save button to save the current report definition.  You will be prompted for a report<br>
				code or to confirm overwriting an existing definition.</dd>
		<dt>Delete</dt>
			<dd>Press Delete to permanently delete the report definition.  You will be prompted to confirm this action.</dd>
		<dt>Save as Default</dt>
			<dd>Press Save as Default to save the current settings as the default to be used when creating<br>
				new reports.  There are some built-in defaults that will be used if you have not saved<br>
				any default settings.</dd>
		<dt>Create New</dt>
			<dd>Press the Create New button to create a new report using the default settings.  Any unsaved<br>
				changes to the current report will be lost.</dd>
		<dt>Export</dt>
			<dd>Press the Export button to export the current report settings to a file.  You will be<br>
				prompted for a filename.</dd>
		<dt>Import</dt>
			<dd>Press the Import button to import settings from a file.  You will be prompted for a <br>
				filename, or can browse for the file you want to use.</dd>
	</dl>

	<h3><a name=options_help>Report Options</a></h3>
	<dl>
		<dt>Data Source</dt>
			<dd>Select the data source for this report.  Default will use the default data source specified in<br>
				webfwlog.conf.  Database will use data logged in a database using the ULOG or NFLOG target of linux<br>
				netfilter, Snort IDS or other database logs.  You can also select one or more tables or views to use,<br>
				overriding the default specified in webfwlog.conf.  Syslog will use system log files.</dd>
		<dt>File Name</dt>
			<dd>For syslog data, enter the filename(s) to parse separated by spaces.<br>
				Multiple files can also be specified using the syntax of the shell available to PHP,<br>
				e.g., messages{,.1.gz}</dd>
		<dt>Title</dt>
			<dd>Enter a title for this report which will appear in the report heading.</dd>
		<dt>Rows per page</dt>
			<dd>This is the number of rows that will appear on each page of output.  Enter 0 or leave blank<br>
				to display all rows.</dd>
		<dt>Page Refresh Rate</dt>
			<dd>The report will refresh at this interval in seconds if your browser supports meta-refresh.<br>
				Setting to zero disables refresh.</dd>
		<dt><a name=cache_every>Update Hostname Cache</a></dt>
			<dd>Check the Update Hostname Cache box to update the <a href='$self?action=use+report&select_report=".urlencode("$name")."#hostname'>hostname and services caches</a> every time<br>
				the report is run, but be aware that this may dramatically increase the time needed to run a report.<br>
				This setting is saved with the report definition.</dd>
		<dt>Populate Hostname Cache</dt>
			<dd>Check the Populate Hostname Cache box to populate the <a href='$self?action=use+report&select_report=".urlencode("$name")."#hostname'>hostname and services caches</a> every<br>
				time the report is run, including hosts and services for selected rows not appearing in the result, and<br>
				without resolving the new entries.  The caches can then be updated using the<br>
				<a href='$self?action=use+report&select_report=".urlencode("$name")."#cache_sep'>Update Cache Button</a>
				from the main page or from the report editor at a later time.<br>
				This setting is saved with the report definition.</dd>
		<dt>Populate Cache Full</dt>
			<dd>Check the Populate Cache Full box to populate the <a href='$self?action=use+report&select_report=".urlencode("$name")."#hostname'>
				hostname and services caches</a> every<br>
				time the report is run, but without resolving the new entries.  The caches can then be updated using the<br>
				<a href='$self?action=use+report&select_report=".urlencode("$name")."#cache_sep'>Update Cache Button</a>
				from the main page or from the report editor at a later time.<br>
				This setting is saved with the report definition.</dd>
		<dt><a name=cache_sep>Update Cache button</a></dt>
			<dd>Press the Update Cache button to update the <a href='$self?action=use+report&select_report=".urlencode("$name")."#hostname'>hostname and services caches</a> immediately.<br>
				<br>
				Please be aware that this may take a LONG time depending upon how many new unique IPs are<br>
				found.  You may cancel this operation at any time, and any hostnames already <br>
				updated will be saved and not need to be updated again.</dd>
	</dl>
";
$columns_doc = "
	<h3><a name=columns_help>Columns to Include Menu</a></h3>
	<dl>
		<dt>Columns to Include</dt>
			<dd>You may include any columns you wish in the report and in any order.  To include a column in the<br>
				report enter a number in the box next to the column description.  The columns will appear in the<br>
				report in numerical order as entered.  To remove a column from the report make the box blank.  If you<br>
				wish to insert a column between two columns you can enter a decimal fraction, e.g. 3.5 will go between<br>
				3 and 4.  You can enter 0 to place a column first.  If two columns have the same number the order in<br>
				which they will appear is not defined.<br>
				<br>
				Only some of all possible columns are shown on the report editing menu.  To see the remaining columns<br>
				press the More button.  Pressing the Refresh button will update the display of the columns in current<br>
				numerical order, and renumber the columns beginning with 1.<br>
				<br>
				Not all of the columns shown will be available for every log format.  If you select a column that<br>
				is not in your database logs an error will occur; if your logs are in files the column will be blank or 0<br>
				depending upon the type of column, or left out entirely.</dd>
		<dt>Links</dt>
			<dd>Check the link box next to a column to include a hyperlink in each cell for that column in the<br>
				report.  Generally, clicking on a link in a report will filter the report by the item in the cell<br>
				selected.  For example, if you have a report that has tcp, udp and icmp packets included, clicking on<br>
				a link in the protocol column that shows &quot;tcp&quot; will redisplay the report with all other settings the<br>
				same but showing only rows for tcp packets.  You can further filter the report by clicking on a link<br>
				in another column.  Continuing the example, clicking on a link in the source IP column will filter the<br>
				report by the source IP selected, and you will now see a report showing only tcp packets from that<br>
				source IP.<br>
				<br>
				One exception to this is the Count column on summarized reports.  Clicking on a link in this column<br>
				will show an unsummarized report showing the individual logged entries that make up that line.  For<br>
				example, if the count column shows &quot;12&quot; clicking on the link will show the 12 logged entries.<br>
				<br>
				The other exception is the Packet column, which shows a unique auto-generated id for each logged<br>
				packet in database log, or the line number for file logs.  Clicking on a link in the Packet column will<br>
				show all the details for that packet whether or not they appear in the report.<br>
				<br>
				Certain columns do not have checkboxes for links because links would not be meaningful.  These include<br>
				all date/time columns as well as looked-up columns such as hostnames and service names.<br>
				<br>
				There are also always links in the column headings on reports.  Clicking on a link in a column heading<br>
				will sort the report by that column.  Clicking on the column heading again will reverse the order in<br>
				which the column is sorted.</dd>
";
if ($config["allow_raw_sql"]) $columns_doc = $columns_doc . "
		<dt>Arbitrary Column</dt>
			<dd>
				If your data is logged to a database, you can enter an arbitrary column definition in the blank text box and<br>
				this will be added to SQL SELECT statement as-is.  Checking the &quot;Grp&quot; box will add this column to<br>
				the GROUP BY clause, which MUST be selected if the column definition does not contain aggregate functions<br>
				such as max(), min() or sum(), and MUST NOT be selected otherwise.  The summarize box should also be selected<br>
				if this definition includes aggregate functions.<br>
				<br>
				It is up to you to ensure this is a valid SQL column definition for your database server, that Grp is <br>
				selected if needed, and that a link for drill-down, if selected, makes sense.<br>
				<br>
				If you data is logged to files this control has no effect.</dd>";
$columns_doc = $columns_doc . "
	</dl>
";
$sort_doc = "
	<h3><a name='sort_help'>Sort Order Menu</a></h3>
	<dl>
		<dt>Summarize Report</dt>
			<dd>Check the Summarize Report box to group the report by the columns selected for the report.  For example,<br>
				if you have a report with the Protocol, Source IP and Destination port columns included, and have 15<br>
				logged packets from one source IP to tcp port 25, and 34 from another source IP to tcp port 25, you<br>
				would get a two-line report, with 15 and 34 appearing the Count column, which you would normally<br>
				include in a summarized report<br>
				<br>
				For database logs, summarizing a report means invoking the &quot;GROUP BY&quot; clause of a SQL query, and you<br>
				cannot include an aggregated column in an unsummarized report, such as Count, Earliest and Latest.  You will<br>
				receive an error message if you try to do so.  All other selected columns will be included in the GROUP BY<br>
				clause.<br>
				</dd>
		<dt>Sort Order</dt>
			<dd>The report will be sorted in the order shown here.  To change to sort order of a report, put a number<br>
				in the box next to the column.  The columns will be sorted in the report in numerical order as entered.<br>
				To remove a column from the sort order make the box blank.  If you wish to insert a column into the sort<br>
				order between two columns you can enter a decimal fraction, e.g. 3.5 will go between 3 and 4.  You can<br>
				enter 0 to put a column first in the sort order.  If two columns have the same number the order in which<br>
				they will sorted is not defined.<br>
				<br>
				Pressing the Refresh button will update the display of the sort order in current numerical order,<br>
				and renumber the sort order beginning with 1.<br>
				<br>
				To sort a column in reverse order check the Desc box.<br>
				<br>
				Only some of all possible columns that can be included in the sort order are shown on the report editing<br>
				menu.  To see the remaining columns press the More button.</dd>
	</dl>
";
$criteria_doc = "
	<h3><a name=crit_help>Criteria Menu</a></h3>
	<dl>
		<dt>Criteria Entry</dt>
			<dd>Enter the values that you want to use to restrict the logged packets that will be included in the report.<br>
				Check the Inv box to invert the test and include only logged packets that do NOT match the value entered.<br>
				If your logged data do not include a field, adding selection criteria for that field may result in no<br>
				records being selected.</dd>
		<dt><a name=dates>Dates</a></dt>
			<dd>Dates can be entered using the <a href='http://www.gnu.org/software/tar/manual/html_node/Date-input-formats.html#Date-input-formats'>GNU date
				syntax.</a>  This means that you can enter things like &quot;yesterday&quot;<br>
				or &quot;last week&quot; and it will be saved this way, meaning you can have a report that always shows you<br>
				recent activity, for example.<br>
				<br>
				The Min date and Max date values are used to restrict the report to packets within the specified range.<br>
				<br>
				This paragraph relates to ulog database logs only.  Ulog records the timestamp of a packet in the<br>
				oob_time_sec field in the database, and as older linux kernels did not record a timestamp for locally<br>
				generated packets this field would be NULL or 0 for such packets.  As a workaround, ulog provides the LOCAL<br>
				plugin which would record the time of the logging host in the local_time field of the database.  Values<br>
				entered for Min date and Max date are matched against the local_time field if it exists, otherwise<br>
				against the oob_time_sec field.  If both fields exist you can force a match against oob_time_sec by checking<br>
				the oob time box.  With recent kernels the local_time field is not useful or needed, and in the absence of<br>
				this field oob_time_sec will always be used.  In other words, with recent linux kernels you can ignore<br>
				this paragraph.</dd>
		<dt>Local Host<br>
			Log Label<br>
			Input Interface<br>
			Output Interface<br>
			Source MAC<br>
			Destination MAC<br>
			MAC String</dt>
			<dd>You can select packets based on the input and/or output interfaces, MAC address, log label, and also the<br>
				local hostname using POSIX extended regular expressions for file logs, and for database logs the matching used<br>
				by the regualar expression operator for your database server.  This is usually POSIX extended by default but<br>
				can be changed in some cases; see the documentation for your database server.<br>
				<br>
				For example, if you want to include all packets that have DROP in the log label simply enter &quot;DROP&quot; in the box.<br>
				However, if you want to match only packets that have the exact text &quot;DROP&quot; as the log label then enter &quot;^DROP$&quot;<br>
				in the box.<br>
				<br>
				For Netfilter, the log label is an optional user-defined argument (eg: &quot;log-prefix&quot;) to the LOG, ULOG or NFLOG target.<br>
				For Ipfilter, the log label is &quot;&lt;group&gt;:&lt;rule number&gt; &lt;action&gt; &lt;log-tag&gt;&quot;, where log-tag is optional.
					man ipmon for more info.<br>
				For Ipfw, the log label is &quot;&lt;rule number&gt; &lt;action&gt;&quot;.  Man ipfw for more information.<br>
				For Ipchains, the log prefix is the target name, such as ACCEPT or DENY.<br>
				For Snort, the log label is the classification.  See the snort documentation for details.<br>
				For Cisco IOS routers, the log label is &quot;&lt;rule number&gt; &lt;action&gt;&quot;, where action is Deny or Permit.<br>
				For Cisco PIX routers, the log label is always &quot;Deny&quot;<br>
				For Netscreen, the log label is the action.  See Netscreen documentation.<br> 
				<br>
				If your packets are logged in a database, you should be aware that depending upon the column type for these<br>
				fields in your database, white space may or may not be trimmed from the beginning and end of the value stored<br>
				in the database and you need to take this into account when you formulate your regular expression.  Also,<br>
				whitespace will ALWAYS be trimmed from the beginning and end of what you enter here, so you will need to use<br>
				bracket expressions if you want to begin or end your RE with white space, e.g. &quot;^[[:space:]]+&quot; to match<br>
				whitespace at the beginning of the value using POSIX extended RE's.</dd>
		<dt>TCP Source Port<br>
			TCP Destination Port<br>
			UDP Source Port<br>
			UDP Destination Port<br>
			ICMPv4 Type<br>
			ICMPv4 Code<br>
			ICMPv6 Type<br>
			ICMPv6 Code<br></dt>
			<dd>Enter the tcp port, udp port or icmp type and/or code you want to include in your report.  You can<br>
				enter a single value, a range of values separated with a &quot;:&quot;, or a comma-delimited list of values or<br>
				or ranges.  For example, entering &quot;22:25, 80, 110&quot; will select packets for that field with values<br>
				from 22 to 25, or a value of  80, or a value of 110.<br>
				Note that entering a value here will only affect packets for the appropriate protocol, and all packets<br>
				for other protocols will still be included in the report.  If you only want to select one protocol use<br>
				the <a href='$self?action=use+report&select_report=".urlencode("$name")."#protocol'>IP Protocol selector</a>.</dd>
		<dt><a name=protocol>IP Protocol</a></dt>
			<dd>Enter the IP protocols you want to include as a name or number, i.e., &quot;6&quot; and &quot;tcp&quot; are equivalent.<br>
				You can enter a single protocol, a comma-delimited list or a numeric range of protocols separated by a&quot;:&quot;</dd>
		<dt>TCP Options</dt>
			<dd>Check the boxes for the TCP options by which you want to select packets.  Check the exact match box<br>
				if you want to select those packets which have exactly the selected options.  For example, without the <br>
				exact match box, selecting SYN will include packets with just the SYN bit set, as well as those with<br>
				both the SYN and ACK bits set, etc.  On the other hand, checking the exact match box would include<br>
				only those with just the SYN bit set.<br>
				<br>
				Note that making selections here will only affect tcp packets.  All packets for other protocols will<br>
				still be included in the report.  If you only want to select tcp packets use the <a href='$self?action=use+report&select_report=".urlencode("$name")."#protocol'>IP Protocol selector</a>.</dd>
		<dt>Source IP<br>
			Destination IP<br>
			ICMP Redirect Gateway</dt>
			<dd>Enter the IP address you want to include, with an optional prefix, in either dotted-quad IPv4 address or any valid IPv6<br>
				address notation.  You may include a prefix such as /24 or /64 to specify a address range, which for IPv4 may be<br>
				specified as a netmask, i.e., xxx.xxx.yyy.yyy/255.255.255.0 and xxx.xxx.yyy.yyy/24 are equivalent, except that if your<br>
				data is logged to a	postgresql database with a column type of inet for these columns, you must use prefix notation to<br>
				specify a netmask or an	error will result.  You can specify a single address or a comma-delimited list of addresses.</dd>
		<dt>Min Count<br>
			Max Count<br>
			<dd>For summarized reports, enter the minimum or maximum value for the Count column to include in the report</dd>
		<p>
		<dt><strong>Selectors for the following criteria can be accessed by pressing the More button.</strong></dt>
		</p>
		<dt>Latest Earliest<br>
			Earliest Latest</dt>
			<dd>Enter the most recent value for the Earliest column or the oldest value for the Latest column that you want<br>
				to include in the report.  See also <a href='$self?action=use+report&select_report=".urlencode("$name")."#dates'>discussion about dates</a></dd>
		<dt>IP Family<br>
			IP TOS / IPv6 TC<br>
			IP TTL / IPv6 Hoplimit<br>
			IP Header Length<br>
			IP Total Length<br>
			IP ID<br>
			IP Checksum<br>
			IPv6 Flowlabel<br>
			IPv6 Payload Length<br>
			Firewall Mark<br>
			TCP Sequence Number<br>
			TCP ACK Sequence Number<br>
			TCP Window<br>
			TCP Data Offset<br>
			TCP Urgent Pointer<br>
			TCP Checksum<br>
			UDP Length<br>
			UDP Checksum<br>
			ICMPv4 Echo ID<br>
			ICMPv4 Echo Sequence Number<br>
			ICMPv4 Next hop MTU<br>
			ICMPv6 Echo ID<br>
			ICMPv6 Echo Sequence Number<br>
			Ethernet Protocol<br>
			AH/ESP protocol SPI<br>
			Time &micro;sec
			</dt>
			<dd>Enter the value for these fields for the packets you want to include in your report.  If the entry begins<br>
				with &quot;0x&quot; it will be interpreted as a hexadecimal value.  If the entry begin with &quot;0b&quot; it will be<br>
				interpreted as a binary value.  If the first digit is zero, the entry will be interpreted as an octal value.<br>
				Otherwise the entry will be interpreted as a decimal value.<br>
				<br>
				You can	enter a single value, a range of values separated with a &quot;:&quot;, or a comma-delimited list of values or<br>
				or ranges.  For example, entering &quot;20:100, 1000&quot; will select packets for that field with values<br>
				from 20 to 100, or a value of 1000.<br>
				<br>
				Note that entering values for selectors for particular protocols such as tcp,udp,icmp or ah/esp will only<br>
				affect packets for the appropriate protocol, and all packets for other protocols will still be included in<br>
				the report.  If you only want to select one protocol use the
				<a href='$self?action=use+report&select_report=".urlencode("$name")."#protocol'>IP Protocol selector</a>.<br>
				<br>
				IP Family should be a numeric value for AF_INET or AF_INET6 for IPv4 and IPv6, respectively. AF_INET is 2 on<br>
				most system, but AF_INET6 varies. For linux it is 10, for BSD-ish systems it is 28, 26 for Solaris, and could<br>
				be other values on different systems. Try including the IP Family column and see what values you get for IPv6<br>
				packets.<br>
				<br>
				Note also that the defintions for some fields have changed over time (notably TOS), and interpretation of<br>
				such fields is implementation dependent.</dd>
		<dt>Fragmentation Offset</dt>
			<dd>Check the DF or MF checkbox to include packets with the respective flag set. Enter the fragementation offset<br>
				value for packets to include in the text box.  DF and MF only have meaning for IPv4 packets and are ignored for<br> 
				IPv6 packets</dd>";
if ($config["allow_raw_sql"]) $criteria_doc = $criteria_doc . "
		<dt>Additional SQL WHERE clause</dt>
			<dd>If you data is logged to a database, whatever you enter here will be added to the WHERE clause of the SQL<br>
				query as-is.  This will be enclosed in &quot;(&quot; and &quot;)&quot; as a sub-expression and ANDed with<br>
				any other specified criteria.  When specifying critera, you will need to refer to the
				<a href='$self?action=use+report&select_report=".urlencode("$name")."#fieldnames'>database fieldnames</a><br>
				and not to the displayed column labels.<br>
				<br>
				If your data is logged to files this control has no effect.</dd>
		<dt>SQL HAVING clause</dt>
			<dd>If you data is logged to a database, what you enter here will be added to the HAVING clause of the SQL query as-is.<br>
				You would normally put here selection criteria based on aggregate functions, such as max(), min() or sum.<br>
				For example &quot;sum(ip_datalen)>1000.&quot; You should not put here criteria not based on aggregate functions;<br>
				these should go in the WHERE clause instead.<br>
				<br>
				If your data is logged to files this control has no effect.</dd>";
$criteria_doc = $criteria_doc . "
	</dl>
	<h3>Miscellaneous</h3>
	<dl>
		<dt><a name=hostname>Hostname Cache</a></dt>
			<dd>If you have created the <em>hostnames</em> table during setup, you will be able to include a column in your<br>
				reports with reverse DNS lookups for source and destination IP addresses.  If the table does not exist<br>
				the hostname columns will be ignored; for performance reason Webfwlog will not attempt to resolve<br>
				hostnames without a cache.<br>
				<br>
				The cache can be updated in one of two ways, <a href='$self?action=use+report&select_report=".urlencode("$name")."#cache_every'>every time</a> a report is run
					or as a <a href='$self?action=use+report&select_report=".urlencode("$name")."#cache_sep'>separate operation</a>.  Note<br>
				that this can take a long time if it has been awhile since you last updated the cache or have never<br>
				updated the cache</dd>
		<dt>Service Name Cache</dt>
			<dd>If you have created the <em>services</em> table during setup, you will be able to include a column in your<br>
				reports with the name of tcp and udp services, derived from the <em>services</em> file.  If the table<br>
				does not exist the service name columns will be ignored; for performance reason Webfwlog will not<br>
				attempt to resolve service names without a cache.<br>
				<br>
				The cache can be updated in one of two ways, <a href='$self?action=use+report&select_report=".urlencode("$name")."#cache_every'>every time</a> a report is run
					or as a <a href='$self?action=use+report&select_report=".urlencode("$name")."#cache_sep'>separate operation</a>.  Note<br>
				that this can take a long time if it has been awhile since you last updated the cache or have never<br>
				updated the cache</dd>";
if ($config["allow_raw_sql"]) {
$criteria_doc = $criteria_doc . "
		<dt><a name=fieldnames>Field Name cross-reference</a></dt>
			<dd>When specifying criteria in the additional WHERE clause, you must refer to field names as they exist in<br>
				database.  Following is a cross-reference from the column label to the field name for ulogd:</dd>
			<dd>
			<table>
";
			foreach ($longnames as $field => $name) {
				switch ("$field") {
				// Don't print these
					case "local_time":
					case "tcp_syn":
					case "tcp_ack":
					case "tcp_fin":
					case "tcp_rst":
					case "tcp_psh":
					case "tcp_urg":
					case "tcp_urgp":
					case "extra":
					case "src_service":
					case "dst_service":
					case "src_host":
					case "dst_host":
					case "count":
					case "tcp_options":
					case "earliest":
					case "latest":
					case "oob_earliest":
					case "oob_latest":
					case "sport":
					case "dport":
					case "icmptype":
					case "icmpcode":
					case "icmpechoid":
					case "icmpechoseq":
						break;
					default:
						$criteria_doc = $criteria_doc . "<tr><td style='padding-right: 5em; '>$name</td><td>$field</td></tr>\n";
						break;
				}
			}
$criteria_doc = $criteria_doc . "
			</table>
			</dd>
";
}
$criteria_doc = $criteria_doc . " 
    </dl>
";
?>
<tr>
<td>
<?php
	switch ("$doc_page") {
		case "editor":
		print "<p>$intro_doc" . "$columns_doc" . "$sort_doc" . "$criteria_doc";
		break;
		case "selection":
		print "<p>$columns_doc";
		break;
		case "sort":
		print "<p>$sort_doc";
		break;
		case "criteria":
		print "<p>$criteria_doc";
		break;
	}
?>
</td>
</tr>

<!-- vim:set ts=4: -->
