Script Documentation Writing
Scripts are used by more than just their author, so scripts must
have documentation. NSE modules need documentation so developers can
use them in their scripts. NSE's documentation system, described in
this section, aims to meet both these needs. While reading this
section, you may want to browse NSE's online documentation, which is
generated using this system. It is at
http://nmap.org/nsedoc/.
NSE uses a customized version of the
LuaDoc
documentation system called NSEDoc.
The documentation for scripts
and modules is contained in their source code, as
comments with a special form.
Example 9.5
is an NSEDoc comment taken from the
stdnse.print_debug() function.
Example 9.5. An NSEDoc comment for a function
--- Prints a formatted debug message if the current verbosity level is greater
-- than or equal to a given level.
--
-- This is a convenience wrapper around
-- <code>nmap.print_debug_unformatted()</code>. The first optional numeric
-- argument, <code>verbosity</code>, is used as the verbosity level necessary
-- to print the message (it defaults to 1 if omitted). All remaining arguments
-- are processed with Lua's <code>string.format()</code> function.
-- @param level Optional verbosity level.
-- @param fmt Format string.
-- @param ... Arguments to format.
Documentation comments start with three dashes:
---. The body of the comment is the description
of the following code. The first paragraph of the description should
be a brief summary, with the following paragraphs giving more
detail. Special tags starting with @ mark off
other parts of the documentation. In the above example you see
@param, which is used to describe each parameter
of the function. A complete list of the documentation tags is found
in the section called “NSE Documentation Tags”.
Text enclosed in the HTML-like <code> and
</code> tags will be rendered in a
monospace font. This should be used for variable and function names,
as well as multi-line code examples. When a sequence of lines start
with the characters “* ”, they will
be rendered as a bulleted list.
It is good practice to document every public function and table in a
script or module. Additionally every script and module should have
its own file-level documentation. A documentation comment at the
beginning of a file (one that is not followed by a function or table
definition) applies to the entire file. File-level documentation can
and should be several paragraphs long, with all the high-level
information useful to a developer using a module or a user running a
script.
Example 9.6
shows documenatation for the comm module (with a
few paragraphs removed to save space).
Example 9.6. An NSEDoc comment for a module
--- Common communication functions for network discovery tasks like
-- banner grabbing and data exchange.
--
-- These functions may be passed a table of options, but it's not required. The
-- keys for the options table are <code>"bytes"</code>, <code>"lines"</code>,
-- <code>"proto"</code>, and <code>"timeout"</code>. <code>"bytes"</code> sets
-- a minimum number of bytes to read. <code>"lines"</code> does the same for
-- lines. <code>"proto"</code> sets the protocol to communicate with,
-- defaulting to <code>"tcp"</code> if not provided. <code>"timeout"</code>
-- sets the socket timeout (see the socket function <code>set_timeout()</code>
-- for details).
-- @author Kris Katterjohn 04/2008
-- @copyright Same as Nmap--See http://nmap.org/book/man-legal.html
There are some special considerations when documenting scripts as
opposed to functions and modules. Some information that might be put
in an @-tag in a comment should go in one of the
special script variables instead. (Script variables are described in
the section called “Script Format”.) Specifically, the script's
description should be in the description variable
rather than in a documentation comment, and the information that
would go in @author and
@copyright should go in the variables
author and license instead.
NSEDoc knows about these variables and will use them in preference
to fields in the comments. Scripts should also have an
@output tag showing sample output.
Example 9.7
shows proper form for script-level documentation, using a
combination of documentation comments and NSE variables.
Example 9.7. An NSEDoc comment for a script
description = [[
Maps IP addresses to autonomous system (AS) numbers.
The script works by sending DNS TXT queries to a DNS server which in
turn queries a third-party service provided by Team Cymru
(team-cymru.org) using an in-addr.arpa style zone set up especially for
use by Nmap.
]]
---
-- @usage
-- nmap --script asn-query.nse [--script-args dns=<DNS server>] <target>
-- @args dns The address of a recursive nameserver to use (optional).
-- @output
-- Host script results:
-- | AS Numbers:
-- | BGP: 64.13.128.0/21 | Country: US
-- | Origin AS: 10565 SVCOLO-AS - Silicon Valley Colocation, Inc.
-- | Peer AS: 3561 6461
-- | BGP: 64.13.128.0/18 | Country: US
-- | Origin AS: 10565 SVCOLO-AS - Silicon Valley Colocation, Inc.
-- |_ Peer AS: 174 2914 6461
author = "jah, Michael"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"discovery", "external"}
Compiled NSE modules are also documented with NSEDoc, even though
they have no Lua source code. Each compiled module has a file
<modulename>.luadoc
that is kept in the nselib directory alongside
the Lua modules. This file lists and documents the functions and
tables in the compiled module as though they were written in Lua.
Only the name of each function is required, not its definition (not
even end). You must use the
@name and @class tags when
documenting a table to assist the documentation parser in
identifying it. There are several examples of this method of
documentation in the Nmap source distribution.
This is a list of tags understood by NSEDoc and their purpose.
@param
Describes a function parameter. The first word following
@param is the name of the parameter
being described. The tag should appear once for each
parameter of the function.
@see
Adds a cross-reference to another function or table.
@return
Describes a return value of a function.
@return may be used multiple times for
multiple return values.
@usage
Gives an example of the usage of a function or script. In
the case of a function, the example is Lua code; for a
script it is an Nmap command line.
@usage may be given more than once.
@name
Defines a name for the function or table being documented.
This tag is normally not necessary, as NSEDoc infers the
name through code analysis.
@class
Defines the “class” of the thing being
modified: function,
table, or module.
Like @name, this is normally inferred
automatically.
@field
In the documentation of a table, describes the value of a
named field.
@args
Describes a script argument, as used with the
--script-args option (see
the section called “Arguments to Scripts”). The first word after
@args is the name of the argument, and
everything following that is the description. This tag is
special to script-level comments.
@output
Shows sample output of a script. This tag is special to
script-level comments.
@author
Lists an author of a module. It may be given more than
once. Don't use this tag in script documentation; use the
author variable instead.
@copyright
Describes the copyright of a module. Don't use this tag in
script documentation; use the license
variable instead.