mirror of
https://github.com/nmap/nmap.git
synced 2026-01-25 07:39:02 +00:00
Document the socket, pcap, and dnet functions in nselib/nmap.luadoc.
This commit is contained in:
@@ -1103,337 +1103,10 @@ action refer to <xref linkend="nse-tutorial-action"/>.
|
||||
classical network uses: Users create a socket, connect it to a
|
||||
remote address, send and receive data and close the socket again.
|
||||
Everything up to the Transport layer (which is either TCP, UDP or
|
||||
SSL) is handled by the library. The following socket API methods
|
||||
are supported:
|
||||
SSL) is handled by the library.
|
||||
</para>
|
||||
</sect3>
|
||||
|
||||
<para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>nmap.new_socket()</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>new_socket()</literal> Nmap call returns an
|
||||
NSE socket object which is the recommended method for network
|
||||
I/O. It provides facilities to perform communication using the
|
||||
UDP, TCP and SSL protocol in a uniform manner.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>status, error = socket_object:connect(hostid, port, [protocol])</option>
|
||||
</term>
|
||||
|
||||
<listitem>
|
||||
|
||||
<para>
|
||||
The connect method of NSE socket objects will put
|
||||
the socket in a state ready for communication. It
|
||||
takes as arguments a host descriptor (either an IP
|
||||
address or a host name), a port number and optionally
|
||||
a protocol. The protocol must be one of
|
||||
<literal>tcp</literal>, <literal>udp</literal> or
|
||||
<literal>ssl</literal>. By default the connect call
|
||||
will attempt to open a TCP connection. On success the
|
||||
returned value of status is
|
||||
<literal>true</literal>. If the connection attempt has
|
||||
failed, the error value contains a description of the
|
||||
error condition stored as a string.
|
||||
Those strings are
|
||||
taken from the <function> gai_strerror()</function>
|
||||
C function. They are (with the errorcode in parentheses):</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><quote>Address family for hostname not supported</quote> (<literal>EAI_ADDRFAMILY</literal>)</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><quote>Temporary failure in name resolution</quote> (<literal>EAI_AGAIN</literal>)</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><quote>Bad value for ai_flags</quote> (<literal>EAI_BADFLAGS</literal>)</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><quote>Non-recoverable failure in name resolution</quote> (<literal>EAI_FAIL</literal>)</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><quote>ai_family not supported</quote> (<literal>EAI_FAMILY</literal>)</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><quote>Memory allocation failure</quote> (<literal>EAI_MEMORY</literal>)</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><quote>No address associated with hostname</quote> (<literal>EAI_NODATA</literal>)</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><quote>Name or service not known</quote> (<literal>EAI_NONAME</literal>)</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><quote>Servname not supported for ai_socktype</quote> (<literal>EAI_SERVICE</literal>)</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><quote>ai_socktype not supported</quote> (<literal>EAI_SOCKTYPE</literal>)</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><quote>System error</quote> (<literal>EAI_SYSTEM</literal>)</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>In addition to these standard system error based messages are the following two NSE-specific errors:</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<indexterm><primary>SSL</primary><secondary>in NSE</secondary></indexterm>
|
||||
<para><quote>Sorry, you don't have OpenSSL.</quote> occurs
|
||||
if <literal>ssl</literal> is passed as third argument, but Nmap was compiled
|
||||
without OpenSSL support.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><quote>invalid connection method</quote> occurs if
|
||||
the second parameter is not one of <literal>tcp</literal>, <literal>udp</literal>, <literal>ssl</literal>.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>status, error = socket_object:send(data)</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The send method sends the data contained in the
|
||||
<literal>data</literal> string through an open
|
||||
connection. On success the returned value of status is
|
||||
<literal>true</literal>. If the send operation
|
||||
has failed, the error value contains a description of
|
||||
the error condition stored as a string. The error strings are:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><quote>Trying to send through a closed socket</quote>—if there was no
|
||||
call to socket_object:connect before the send operation.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><quote>TIMEOUT</quote>—if the operation took longer than the
|
||||
specified timeout for the socket.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><quote>ERROR</quote>—if an error occurred inside the underlying
|
||||
Nsock library.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><quote>CANCELLED</quote>—if the operation was cancelled.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><quote>KILL</quote>—if for example the script scan is aborted due
|
||||
to a faulty script.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><quote>EOF</quote>—if an EOF was read—will probably not occur
|
||||
for a send operation.</para>
|
||||
</listitem>
|
||||
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>status, value = socket_object:receive()</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The receive method does a non-blocking receive operation on
|
||||
an open socket. On success the returned value of
|
||||
<literal>status</literal> is
|
||||
<literal>true</literal> and the received data is stored in
|
||||
<literal>value</literal>. If receiving data has failed,
|
||||
<literal>value</literal> contains a description of the error
|
||||
condition stored as a string. A failure occurs for example
|
||||
if receive is called on a closed socket. The receive call
|
||||
returns to the NSE script all the data currently stored
|
||||
in the receive buffer of the socket. Error conditions
|
||||
are the same as for the send operation.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>status, value = socket_object:receive_lines(n)</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Tries to receive at least <replaceable>n</replaceable>
|
||||
lines from an open connection. A line is a string
|
||||
delimited with <literal><quote>\n</quote></literal> characters. If
|
||||
it was not possible to receive at least
|
||||
<replaceable>n</replaceable> lines before the operation times
|
||||
out a TIMEOUT error occurs. On the other hand, if more
|
||||
than <replaceable>n</replaceable> lines were received, all are
|
||||
returned, not just <replaceable>n</replaceable>. Use
|
||||
<literal>stdnse.make_buffer</literal> to guarantee one line
|
||||
is returned per call. On success
|
||||
the returned value of <replaceable>status</replaceable> is
|
||||
<literal>true</literal> and the received data is
|
||||
stored in <replaceable>value</replaceable>. If the connection
|
||||
attempt has failed, <replaceable>value</replaceable> contains
|
||||
a description of the error condition stored as string.
|
||||
Error conditions are the same as for the send operation.
|
||||
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>status, value = socket_object:receive_bytes(n)</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Tries to receive at least <replaceable>n</replaceable>
|
||||
bytes from an open connection. On success the returned
|
||||
value of <replaceable>status</replaceable> is <literal>true</literal> and the
|
||||
received data is stored in
|
||||
<replaceable>value</replaceable>. If operation fails,
|
||||
<replaceable>value</replaceable> contains a description of the
|
||||
error condition stored as a string. Similarly to
|
||||
<literal>receive_lines()</literal>
|
||||
<replaceable>n</replaceable> is the minimum amount of
|
||||
characters we would like to receive. If more arrive,
|
||||
we get all of them. If fewer than <replaceable>n</replaceable> characters arrive
|
||||
before the operation times out, a TIMEOUT error occurs.
|
||||
Other error conditions are the same as for the send operation.
|
||||
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>status, value = socket_object:receive_buf(func/"string", keeppattern)</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
|
||||
The <literal>receive_buf</literal> method reads data
|
||||
from the network until it encounters the given delimiter
|
||||
string (or matches the function passed in). Only data
|
||||
which occurs before the delimiter is returned, and the
|
||||
delimiter is then erased. This function continues to
|
||||
read from the network until the delimiter is found or
|
||||
the function times out. If data is read beyond the
|
||||
delimiter, that data is saved in a buffer for the next
|
||||
call to <literal>receive_buf</literal>. This buffer is
|
||||
cleared on subsequent calls to other Network I/O API
|
||||
functions.</para>
|
||||
|
||||
<para>The <literal>receive_buf</literal> method takes
|
||||
two arguments. The first one is either a string or
|
||||
a function. Strings are passed to
|
||||
Lua's <literal><ulink role="hidepdf"
|
||||
url="http://www.lua.org/manual/5.1/manual.html#5.4">string.find</ulink></literal>
|
||||
function as the second (pattern) parameter, with the
|
||||
buffer data being searched. If the
|
||||
first <literal>receive_buf</literal> argument is a
|
||||
function, it is expected to take exactly one
|
||||
parameter (the buffer) and its return values must be
|
||||
in the same format as <literal>string.find</literal>
|
||||
(offsets to the start and the end of the delimiter
|
||||
inside the buffer, or <literal>nil</literal> if the
|
||||
delimiter is not found). The nselib
|
||||
<literal>match.lua</literal> module provides functions
|
||||
for matching against regular expressions or byte
|
||||
counts. These functions are suitable as arguments
|
||||
to <literal>receive_buf</literal>.</para>
|
||||
|
||||
<para>The second argument
|
||||
to <literal>receive_buf</literal> is a Boolean value
|
||||
which indicates whether the delimiting pattern
|
||||
should be returned along with the received data or
|
||||
discarded. The delimiter is included if <literal>true</literal> is passed as the <literal>keeppattern</literal> argument.</para>
|
||||
|
||||
<para>The return values of <literal>receive_buf</literal> are the same as the other <literal>receive*</literal> functions. A <literal>(status, val)</literal> tuple is returned. The <literal>status</literal> is <literal>true</literal> if the request was successful. The <literal>val</literal> variable contains the returned data, or an error message if the call failed.</para>
|
||||
|
||||
<para>Possible error messages include those described previously for the other
|
||||
<literal>receive*</literal> functions as well as the
|
||||
following:
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><quote>Error inside splitting-function</quote>—if the first argument was
|
||||
a function which caused an error while being called.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><quote>Error in <literal>string.find</literal> (<literal>nsockobj:receive_buf</literal>)!</quote>—if a string
|
||||
was provided as the first argument, and string.find() yielded an
|
||||
error while being called.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><quote>Expected either a function or a string!</quote>—if the
|
||||
first argument was neither a function nor a string.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><quote>Delimiter has negative size!</quote>—if the returned start offset
|
||||
is greater than the end offset.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>status, err = socket_object:close()</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Closes an open connection. On success the returned value of
|
||||
<literal>status</literal> is <literal>true</literal>. If the connection
|
||||
attempt has failed, <literal>value</literal> contains a description
|
||||
of the error condition stored as a string. Currently the only error
|
||||
message is: <quote>Trying to close a closed socket</quote>, which is issued if the socket
|
||||
has already been closed. Sockets are subject to garbage collection.
|
||||
Should you forget to close a socket, it will get closed before it gets
|
||||
deleted (on the next occasion Lua's garbage collector is run).
|
||||
However since garbage collection cycles are difficult to predict, it
|
||||
is considered good practice to close opened sockets.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>status,localip,localport,remoteip,remoteport=socket_object:get_info()</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This function returns information about the socket
|
||||
object. It returns 5 values. If an error occurred, the
|
||||
first value is <literal>nil</literal> and the second
|
||||
value describes the error condition. Otherwise the
|
||||
first value describes the success of the operation and
|
||||
the remaining 4 values describe both endpoints of the
|
||||
TCP connection. If you put the call in a <literal>try()</literal> statement
|
||||
the status value is consumed. The call can be used for example if
|
||||
you want to query an authentication server.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry>
|
||||
<term><option>socket_object:set_timeout(t)</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the time, in milliseconds, after which input and
|
||||
output operations on a socket should time out and
|
||||
return. The default value is 30,000 (30 seconds). The lowest
|
||||
allowed value is 10 ms, since this is
|
||||
the granularity of NSE network I/O.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</para>
|
||||
</sect3>
|
||||
<sect3 id="nse-api-networkio-raw">
|
||||
<title>Raw packet network I/O</title>
|
||||
<indexterm><primary>raw packets</primary><secondary>in NSE</secondary></indexterm>
|
||||
@@ -1460,131 +1133,14 @@ action refer to <xref linkend="nse-tutorial-action"/>.
|
||||
execution. To use the packet capturing inside your script you have to
|
||||
create a socket with
|
||||
<literal>nmap.newsocket()</literal> and later close the socket with <literal>socket_object:close()</literal>—just
|
||||
like with the connection-based network I/O. A more detailed description
|
||||
of the functions for packet capturing follows:
|
||||
like with the connection-based network I/O.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>socket_object:pcap_open(device, snaplen, promisc,
|
||||
test_function, bpf)</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>pcap_open()</literal> call opens the socket for
|
||||
packet capturing. The parameters are:</para>
|
||||
<itemizedlist>
|
||||
<listitem><para><literal>device</literal>—the dnet-style interface name of the device you want to capture from</para></listitem>
|
||||
<listitem><para><literal>snaplen</literal>—defines the length of each packet you want to capture (similar to the <option>-s</option> option to <command>tcpdump</command>)</para></listitem>
|
||||
<listitem><para><literal>promisc</literal>—should be set to <literal>1</literal> if the interface should activate promiscuous mode, and zero otherwise</para></listitem>
|
||||
<listitem><para><literal>test_function</literal>—callback function used to compute the <literal>packet hash</literal></para></listitem>
|
||||
<listitem><para><literal>bpf</literal>—a string describing a Berkeley packet filter expression (like those provided to <command>tcpdump</command>)</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>socket_object:pcap_register(packet-hash)</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Starts the listening for incoming packages. The provided
|
||||
<literal>packet-hash</literal> is a binary string which has to
|
||||
match the hash returned by the
|
||||
<literal>test_function</literal> parameter provided to
|
||||
<literal>pcap_open()</literal>. If you want to receive all
|
||||
packets, just provide the empty string (<literal>""</literal>).
|
||||
There has to be a call to <literal>pcap_register()</literal>
|
||||
before a call to <literal>pcap_receive()</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>status, packet_len, l2_data, l3_data = socket_object:pcap_receive()</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Receives a captured packet. If successful, the return values are:</para>
|
||||
<itemizedlist>
|
||||
<listitem><para><literal>status</literal>—a Boolean with the value <literal>true</literal></para></listitem>
|
||||
<listitem><para><literal>packet_len</literal>—the length of the captured packet which was received (this may be smaller than the actual packet length since packets are truncated when the Libpcap snaplen parameter is smaller than the total packet length)</para></listitem>
|
||||
<listitem><para><literal>l2_data</literal>—data from the second OSI layer (e.g. ethernet headers)</para></listitem>
|
||||
<listitem><para><literal>l3_data</literal>—data from the third OSI layer (e.g. IPv4 headers)</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>Should an error or timeout occur, while waiting for a packet the
|
||||
return values are: <literal>nil,error_message,nil,nil</literal>, where
|
||||
error_message describes the occurred error.</para>
|
||||
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>socket_object:pcap_close()</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>Closes the pcap device.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
<para>
|
||||
Receiving raw packets is a great feature, but it is also only the
|
||||
half job. Now for sending raw packets: To accomplish this NSE has
|
||||
Receiving raw packets is a great feature, but it is also only half
|
||||
the job. Now for sending raw packets: To accomplish this NSE has
|
||||
access to a wrapper around the
|
||||
<literal>dnet</literal> library.<indexterm><primary>libdnet</primary></indexterm>
|
||||
Currently NSE has the ability to send raw ethernet frames via the
|
||||
following API:
|
||||
</para>
|
||||
<para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>dnet_object=nmap.new_dnet()</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Creates and returns a new dnet_object, which can be used to
|
||||
send raw packets.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>dnet_object:ethernet_open(interface_name)</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>Opens the interface defined by the provided
|
||||
<replaceable>interface_name</replaceable> for sending ethernet frames
|
||||
through it. An error (<quote>device is not valid ethernet
|
||||
interface</quote>) is thrown in case the provided argument
|
||||
is not valid.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>dnet_object:ethernet_send(packet)</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sends the provided data as ethernet frame across the previously
|
||||
opened interface. Note that you have to provide the packet
|
||||
including IP header and ethernet header. If there was no
|
||||
previous valid call to <literal>ethernet_open()</literal> an
|
||||
error is thrown (<quote>dnet is not valid opened ethernet
|
||||
interface</quote>).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>dnet_object:ethernet_close()</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>Closes the interface. The only error which may be thrown
|
||||
is the same as for the <literal>ethernet_send()</literal>
|
||||
operation.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
</sect3>
|
||||
</sect2>
|
||||
@@ -1739,7 +1295,7 @@ end
|
||||
try = nmap.new_try(catch)
|
||||
|
||||
try(socket:connect(host.ip, port.number))
|
||||
result = try(socket:receive_lines(1));
|
||||
result = try(socket:receive_lines(1))
|
||||
try(socket:send(result))
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
Reference in New Issue
Block a user