From dfbbbf9e9aaef9a90455daecd33054afe8a20141 Mon Sep 17 00:00:00 2001 From: david Date: Thu, 16 Oct 2008 23:04:50 +0000 Subject: [PATCH] Write a short overview of connect-style I/O and include an example. Rewrite the section on raw sockets in NSE. --- docs/scripting.xml | 118 +++++++++++++++++++++++++++++++++------------ 1 file changed, 87 insertions(+), 31 deletions(-) diff --git a/docs/scripting.xml b/docs/scripting.xml index 0a3676582..cea079746 100644 --- a/docs/scripting.xml +++ b/docs/scripting.xml @@ -826,7 +826,7 @@ action refer to . The os entry in the host table is - an array of strings. The strings (maximally 8) are the + an array of strings. The strings (as many as eight) are the names of the operating systems the target is possibly running. Strings are only entered in this array if the target machine is a perfect match for one or more OS @@ -1090,11 +1090,11 @@ action refer to . NSE scripts. The main benefit of NSE's sockets is that they never block on I/O operations, allowing many scripts to be run in parallel. The I/O parallelism is fully transparent to authors of NSE scripts. - In NSE you can either program as if you were using a single non - blocking socket or you can program as if your connection is + In NSE you can either program as if you were using a single + non-blocking socket or you can program as if your connection is blocking. Seemingly blocking I/O calls still return once a specified timeout has been exceeded. Two flavors of Network I/O are - supported: + supported: connect-style and raw packet. Connect-style network I/O @@ -1104,44 +1104,100 @@ action refer to . 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. - + + + An NSE socket is created by calling + nmap.new_socket(), which returns a socket object. + The socket object supports the usual connect, + send, receive, and + close methods. Additionally the functions + receive_bytes, + receive_lines, and + receive_buf allow greater control of the + receiving of data. + + shows the use of connect-style network operations. The + try function is for error handling; see + . + + + Connect-style I/O + +require("nmap") + +local socket = nmap.new_socket() +socket:set_timeout(1000) +try = nmap.new_try(function() socket:close() end) +try(socket:connect(host.ip, port.number)) +try(socket:send("login")) +response = try(socket:receive()) +socket:close() + + Raw packet network I/O raw packetsin NSE - For those cases where the connection oriented approach is too inflexible, + For those cases where the connection-oriented approach is too inflexible, NSE provides script developers with a more powerful option: raw packet network I/O. The greater flexibility comes, however, at the cost of a slightly more complex API. Receiving raw packets is accomplished via a wrapper around Libpcaplibpcap - inside the Nsock library.Nsock - In order to keep the - capturing efficient it works in a three tiered approach: Opening a - device for capturing, registering listeners to it and receiving - packets. With each call to pcap_open() you have - to provide a callback function, which receives the packet (along with - it's layer 2 and 3 headers) and is used to compute a so-called - packet hash. Each call to pcap_register() takes a - binary string as argument. For every packet captured the computed - hash is matched against all registered strings. - Those scripts for which the compare yields true are then provided - with the packet as a return value to pcap_receive(). - The more general the packet hash computing function is kept, - the more scripts may receive the packet and proceed with their - execution. To use the packet capturing inside your script you have to - create a socket with - nmap.newsocket() and later close the socket with socket_object:close()—just - like with the connection-based network I/O. - + inside the + Nsock library.Nsock - - 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 - dnet library.libdnet - + For efficiency, the interface for raw packet capturing + works in three steps. First, a capture device is opened. + Second, listeners are registered with the interface. Third, + packets are received. + + A handle for raw socket reads is created from an + ordinary socket object using the + pcap_open() method. This method takes a + callback function, which computes a so-called packet hash from + a packet along with its headers. This hash can return any + binary string, which is later compared to the strings + registered with the pcap_register() + function. Normally the packet hash callback will extract some + portion of the packet, such as its source address. + + The pcap reader is instructed to listen for certain + packets using the pcap_register() function. + The function takes a binary string which is compared against + the hash value of every packet received. Those packets whose + hashes match any registered strings will be returned by the + pcap_receive() method. Register the empty + string to receive all packets. + + A script then receives packets for which a listener has + been registered by calling the + pcap_receive() method. The method blocks + until a packet is received or a timeout occurs. + + The more general the packet hash computing function is + kept, the more scripts may receive the packet and proceed with + their execution. To use the packet capturing inside your + script you have to create a socket with + nmap.newsocket() and later close the socket + with socket_object:close()—just like + with the connection-based network I/O. + + + 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 + dnet library.libdnet + + Unlike raw socket reads, raw packet writes are not + through a standard socket object. Instead, the function + nmap.new_dnet() creates a dnet object + with ethernet sending methods. Open an interface with the + ethernet_open() method. Send raw ethernet + frames with ethernet_send(). Close the + ethernet handle with ethernet_close when + you're done.