Provided by: netexpect_0.21-2_amd64 bug

NAME

       nexp - A framework for crafting network packets and processing responses

SYNOPSIS

       nexp [-V] [-v] [-t] [-c cmd] [-s seed] [-h] [cmdfile] [args]

INTRODUCTION

       Network Expect (nexp) is a framework that allows to easily build tools that can interact
       with network traffic. Following a script, traffic can be injected into the network, and
       decisions can be taken, and acted upon, based on received network traffic. An interpreted
       language provides branching and high-level control structures to direct the interaction
       with the network.

       Network Expect was heavily influenced and inspired on the Expect program written by Don
       Libes, which allows to "talk" to interactive programs in a scripted fashion. Because of
       this, you will find a lot of similarities between commands in Network Expect and commands
       in Don Libes' Expect. If you are a regular Expect user, it should not be very difficult to
       start writing Network Expect scripts because the basics are the same.

       In Don Libes' Expect, scripts can send data to a process just as if a user were
       interactively typing commands. Then, the script would read the responses sent by the
       application and take decisions accordingly. In Network Expect's case, a script could send
       traffic to a network device and then take decisions based on the received network traffic.
       The type of things that Network Expect can do are usually very low level network
       operations, which usually require writing a custom application in a language like C.

       Network Expect's philosophy is based on the observation that network applications always
       operate on an action-reaction principle in which something is sent to an application
       running on a remote host and a response is then expected.

       Some of the things that Network Expect can do include:

       ·   Generate arbitrary network traffic and inject it into a network at layer 2 or layer 3.

           A wide range of protocols is supported, including IP version 6 as well as protocol
           options like IPv4, IPv6 and TCP options, something that other tools may not offer. For
           example, Network Expect supports TCP MD5 signatures (RFC 2385).

           This Network Expect functionality is very similar to the functionality provided by
           several packet crafting and forging open source tools like Nemesis, Packit, hping,
           Scapy, and others.

       ·   Listen for network traffic and take decisions based on the type of traffic received.

       ·   Open a sniffer trace in PCAP format and replay it after changing some values in the
           original packet capture.

       ·   Emulate network protocols to see how they interact with other speakers of that
           protocol. For example, emulating a TCP server to investigate approaches to
           randomization of TCP Initial Sequence Numbers (ISN) can be easily done in Network
           Expect.

USAGE

       Network Expect reads cmdfile for a list of commands to execute.  Network Expect may also
       be invoked implicitly on systems which support the #! notation by marking the script
       executable, and making the first line in your script:

           #!/usr/bin/nexp -f

       Of course, the path must accurately describe where Network Expect lives; /usr/bin is just
       an example.

       The -c flag prefaces a command to be executed before any in the script. The command should
       be quoted to prevent being broken up by the shell. This option may be used multiple times.
       Multiple commands may be executed with a single -c by separating them with semicolons.
       Commands are executed in the order they appear.

       -V causes Network Expect to print its version number and exit.

       The -s flag allows to specify a random seed that will cause predicatibility of
       pseudo-random numbers generated by Network Expect during execution of a script. In cases
       where Network Expect is used as a protocol fuzzer, this option is useful to be able to
       re-generate a specific test case.

       -v increases the verbosity level. Some commands display additional information when the
       verbosity level is higher.

       The -t flag changes the display format used by commands that display dates or generate
       strings that represent dates.

       Optional arguments are constructed into a list and stored in the variable named argv. argc
       is initialized to the length of argv.

       argv0 is defined to be the name of the script (or binary if no script is used). For
       example, the following prints out the name of the script and the first three arguments:

           puts "$argv0 [lrange $argv 0 2]"

NETWORK LISTENERS AND SPEAKERS

       An integral part of Network Expect is the concept of network listeners and network
       speakers, which are the Network Expect equivalent to spawned processes in Don Libes'
       Expect world. In Expect, the send command sends data to a spawned process, and the expect
       command waits for a specific pattern in the data received from a spawned process.

       In Network Expect, the command to send data to the network, called send_network, uses a
       speaker that specifies how the traffic will be injected.  Network Expect speakers can
       specify IPv4 or IPv6 sockets, in which case packets will be injected at layer 3 and will
       be routed by the operating system kernel.  Network Expect speakers can also specify a
       physical interface, in which case the packet will be injected at layer 2. A network
       speaker can also be a PCAP file (also known as a "savefile"), in which case packets will
       be written to this file instead of injected to the network. Other network speaker types
       include TCP and UDP sockets, in which case the payload generated by the send_network is
       transported by TCP segments or UDP datagrams built by the operating system kernel.

       Network Expect listeners, on the other hand, specify where packets will be read from.
       Listeners can be associated with either a physical interface, or with a PCAP file. In
       either case an optional PCAP filter and/or Wireshark display filter can be associated with
       the listener to limit the type of packets the listener will return. When reading from a
       PCAP file the inter-packet delay between packets can be kept, or packets can be read at
       full speed.

       Both listeners and speakers are created with the Network Expect command spawn_network,
       just as in Don Libes' Expect spawned processes are created with the spawn command.

       The way to specify network listeners and speakers in commands that require them is the
       same regardless of the command. Network listeners are always specified using the -i switch
       (think input) followed by the name of the listener, and network speakers are specified
       using the -o switch (think output) followed by the name of the speaker.

       Network isteners and speakers are created using the spawn_network command. Just as in Don
       Libes' Expect one cannot choose the spawn ID returned by the spawn command, in Network
       Expect it is not possible to choose the name of a network listener or speaker. However,
       one can assign the network listener or speaker name to a variable and use that variable
       whenever a network listener or speaker needs to be specified.

       What follows are a few examples of creation of network listeners and speakers:

           spawn_network -i eth1 icmp and src host 172.16.1.1

       This command creates a network listener on interface eth1 and assigns the filter "icmp and
       src host 172.16.1.1", i.e. "listen only for ICMP messages coming from host 172.16.1.1".
       Since the -o switch has not been specified this command will not create a network speaker.

           spawn_network -o eth0 -r /tmp/packets.pcap tcp and host 172.16.1.1

       This command creates a network speaker on interface eth0 and a network listener that will
       read from the PCAP file "/tmp/packets.pcap" TCP segments to or from the host 172.16.1.1.

           spawn_network -nolistener -6

       This will create a network speaker for injecting IPv6 packets at layer 3. Since the
       -nolistener switch has been specified, this command only creates a network speaker and no
       listener.

           spawn_network -nolistener -w /tmp/mypackets.pcap

       This only creates a speaker that will write packets to the PCAP file
       "/tmp/mypackets.pcap". Note that when writing packets to a PCAP file, injection
       implicitley takes place at layer 2, and using an Ethernet header. This must be taken into
       consideration when specifying the packet to send using the send_network command.

       Network Expect listeners and speakers play a very important role in the operation of
       Network Expect so becoming confortable with them is key to understanding Network Expect's
       philosophy.

NUMERIC SPECIFICATIONS

       When defining packets, Network Expect allows to specify values for most fields in protocol
       headers using a syntax that gives great flexibility. This syntax allows to make the value
       of a field change with each packet that is generated. The syntax is better presented with
       an example. Suppose that we have an hypothetical protocol field called port that is used
       to specify a numeric value at packet generation time. The following numeric specifications
       can be used to specify the actual value

       ·    port = 'telnet' (fixed): the generated value will always be 23, telnet's port number.

       ·    port = 23 (fixed): the generated value will always be 23.

       ·    port = 23++ (increment): the generated value will be 23 initially, and will be
           incremented by one with each successive packet.

       ·    port = 23-- (increment): the generated value will be 23 initially, and will be
           decremented by one with each successive packet.

       ·    port = 23+=5 (decrement): the generated value will be 23 initially, and will be
           incremented by 5 with each successive packet.

       ·    port = 23-=5 (decrement): the generated value will be 23 initially, and will be
           decremented by 5 with each successive packet.

       ·    port = 23..25 (range): the generated value will start with 23, will be incremented by
           one until it reaches 25, and then will go back to 23.

       ·    port = 25..23 (range): the generated value will start with 25, will be decremented by
           one until it reaches 23, and then will go back to 25.

       ·    port = 'random': the generated value will be a random number in each successive
           packet.

COMMANDS

       Network Expect uses Tcl (Tool Command Language). Tcl provides control flow (e.g., if, for,
       break), expression evaluation and several other features such as recursion, procedure
       definition, etc. Commands used here but not defined (e.g., set, if, exec) are Tcl commands
       (see tcl(3)).  Network Expect introduces additional commands, described below. Unless
       otherwise specified, commands return the empty string.

       Commands are listed alphabetically so that they can be quickly located. However, new users
       may find it easier to start by reading the descriptions of spawn_network, send_network,
       expect_network, and send_expect, in that order.

       barray new | length | delete | examine | dump | slice | cmp | string <args>
           The barray command is used to perform management of variables of type barray (byte
           array.)

           barray new <payload spec> will create and return a new barray variable.

           barray length <barray variable> will return the number of bytes that the barray
           variable uses.

           barray delete <barray variable> will delete a barray variable.

           barray examine <barray variable> [/<FMT>] [<offset>] allows to inspect the contents of
           the specified barray variable, starting at the optional offset, and using the format
           optionally specified with /FMT.  /FMT can include an optional count followed by the
           display format, '<' or '>' to specify little endian or big endian, and the size of
           each element to display. Display formats are strings ('s'), octal ('o'), hexadecimal
           ('x'), signed decimal ('d'), and unsigned decimal ('u'). Sizes are byte ('b'),
           half-word ('h'), and word ('w').

           barray dump <barray variable> produces a hexadecimal dump of the specified barray
           variable.

           barray slice <barray variable> <slice spec> returns a slice of the specified barray
           variable.  slice spec must be in the format <[start]:[end]> where start and end are
           offset into the barray variable. If start is ommited the start offset is 0, and if end
           is ommited the end offset is the end of the barray variable.

           barray cmp <barray variable 1> <barray variable 2> compares two barray variables and
           returns an integer less than, equal to, or greater than zero if the first n bytes of
           barray variable 1 are found, respectively, to be less than, to match, or be greater
           than the first n bytes of barray variable 2.  n is calculated to be the minimum of the
           lengths of both barray variables.

       close_network <listener/speaker name>
           This command closes the network listener and/or speaker referenced by
           <listener/speaker name>. Closing a network listener is not a very important thing to
           do since the operation just releases system resources used by the listener. However,
           closing a network speaker is a very important, especially when the speaker is
           associated with a PCAP file since closing the speaker closes the associated PCAP file.

       expect_network [-timeout <timeout>] [-i <listener ID>] {condition1} {body1} ... [-i
       <listener ID>] {conditionN} {bodyN}
           The expect_network command waits for network traffic from one or more network
           listeners (specified with the -i option) until a condition evaluates to true, until a
           specified time period has passed, or until an end-of-file is seen (when the listener
           is associated with a PCAP file.)

           Conditions from the most recent expect_network_before command are implicitly used
           before any other conditions. Conditions from the most recent expect_network_after
           command are implicitly used after any other conditions.

           Conditions are regular Tcl expressions, and bodies are sets of Tcl commands. If the
           final body is empty, it may be omitted.

           If the arguments to the entire expect_network statement require more than one line,
           all the arguments may be "braced" into one so as to avoid terminating each line with a
           backslash. In this one case, the usual Tcl substitutions will occur despite the
           braces.

           If a condition is the keyword eof, the corresponding body is executed upon end-of-file
           (this is only meaningful when a listener is reading from a PCAP file, not on a live
           capture from an interface.) If a condition is the keyword timeout, the corresponding
           body is executed upon timeout. If no timeout keyword is used, an implicit null action
           is executed upon timeout. The default timeout period is 0.5 seconds but may be set,
           for example to 30, by the command "set timeout 30". An infinite timeout may be
           designated by the value -1.

           If a condition is true, then the corresponding body is executed.  expect_network
           returns the result of the body (or the empty string if no condition was true.) In the
           event that multiple conditions match, the one appearing first is used to select a
           body.

           Each time a new packet arrives, it is decoded and the conditions are evaluated in the
           order they are listed. When a packet is decoded, the values of the different fields in
           the packet are made available to Tcl scripts via Tcl variables. Scripts can use these
           values in an condition for a expect_network command.

           In the following example, a listener for ARP requests on interface eth0 is created and
           then an expect_network command is used to wait for actual ARP requests and respond to
           them with an ARP reply:

               # Spawn a listener for ARP requests
               spawn_network -i eth0 host 192.168.1.1 and {arp[6:2]} == 1

               expect_network {1} {
                   # Received an ARP request, send ARP reply
                   send_network -o eth0 \
                       ether(src = $mymac, dst = $arp(sha) )/ \
                       arp-reply(tha = $arp(sha), tip = $arp(sip), \
                                 sha = $mymac, sip = 192.168.1.1)
                   nexp_continue
               }

           The -timeout flag causes the current expect_network command to use the following value
           as a timeout instead of using the value of the timeout variable.

           Actions such as break and continue cause control structures (i.e., for, proc) to
           behave in the usual way. The command nexp_continue allows expect_network itself to
           continue executing rather than returning as it normally would.

           This is useful for avoiding explicit loops or repeated expect_network statements. The
           following example is part of a fragment to respond to ICMP echo and ARP requests. The
           nexp_continue avoids having to write a second expect_network statement (to look for
           the requests again.)

               # Spawn a listener for ARP requests
               spawn_network -i $interface host $myip and {arp[6:2]} == 1
               set arpl $listener_id

               # Spawn a listener for ICMP messages sent to us
               spawn_network -i $interface icmp and dst host $myip
               set icmpl $listener_id

               expect_network -i $arpl {1} {
                   # Received an ARP request, send ARP reply
                   send_network -o $interface \
                       ether(src = $mymac, dst = $arp(sha) )/ \
                       arp-reply(tha = $arp(sha), tip = $arp(sip), \
                                 sha = $mymac, sip = $myip)
                   nexp_continue
               } -i $icmpl {$icmp(type) == 8} {
                   # Received ICMP echo request, send echo reply
                   send_network -o ip \
                       ip(src = $myip, dst = $ip(src) )/ \
                       icmp-echoreply(id = $icmp(id), seq = $icmp(seq) )/ \
                    raw($raw)
                   nexp_continue
               }

       expect_network_after [expect_args]
           works identically to the expect_network_before except that if conditions from both
           expect_network and expect_network_after evaluate to true, the expect_network
           conditions is used. See the expect_network_before command for more information.

       expect_network_background [expect_args]
           takes the same arguments as expect_network, however it returns immediately. Conditions
           are evaluated whenever a new packet arrives. The expression timeout and default are
           meaningless to expect_network_background and are silently discarded. Otherwise, the
           expect_network_background command uses expect_network_before and expect_network_after
           conditions just like expect_network does.

           Please note that if a condition of the expect_network_background command evaluates to
           true, the command will not continue to listen for traffic unless the body includes a
           nexp_continue command that forces expect_network_background to continue executing.

       expect_network_before [expect_args]
           takes the same arguments as expect_network, however it returns immediately.
           Condition-action pairs from the most recent expect_network_before with the same
           network listener ID are implicitly added to any following expect_network commands. If
           a condition evaluates to true, it is treated as if it had been specified in the
           expect_network command itself, and the associated body is executed in the context of
           the expect_network command. If conditions from both expect_network_before and
           expect_network can evaluate to true, the expect_network_before condition is used.

           Unless overridden by a -i flag, expect_network_before conditions are evaluated against
           the network listener ID defined at the time that the expect_network_before command was
           executed (not when its condition evaluated to true.)

           The -info flag causes expect_network_before to return the current specifications of
           what conditions will be evaluated. By default, it reports on the current network
           listener. An optional network listener ID specification may be given for information
           on that network listener.

           Instead of a network listener specification, the flag -all will cause -info to report
           on all network listeners.

           The output of the -info flag can be reused as the argument to expect_network_before.

       iflist [<-refresh>]

           iflist returns a list that contains the name of all interfaces in the system. This
           list is built when Network Expect starts. If the optional argument -refresh is
           specified then the list is refreshed before returning it.

       nexp_continue
           The command nexp_continue allows expect itself to continue executing rather than
           returning as it normally would.

       nexp_version [[-exit] <version>]
           is useful for assuring that the script is compatible with the current version of
           Network Expect.

           With no arguments, the current version of Expect is returned. This version may then be
           encoded in your script. If you actually know that you are not using features of recent
           versions, you can specify an earlier version.

           Versions consist of two numbers separated by dots. First is the major number. Scripts
           written for versions of Network Expect with a different major number will almost
           certainly not work.  nexp_version returns an error if the major numbers do not match.

           Second is the minor number. Scripts written for a version with a greater minor number
           than the current version may depend upon some new feature and might not run.
           nexp_version returns an error if the major numbers match, but the script minor number
           is greater than that of the running Network Expect.

           With the -exit flag, Expect prints an error and exits if the version is out of date.

       outif <target>
           The outif command returns the outgoing interface that would be used to reach target.
           target can be an IP address or host name.

       packet decode | hash | data | dump | ts | tdelta <args>
           The packet command allows to manage variables of type packet.

           packet decode <packet variable> will decode the specified packet variable, just as if
           the packet was received during the execution of a expect_network command.

           packet hash <packet variable> calculates a hash of the specified packet variable.

           packet data <packet variable> returns a barray variable that contains all of the
           packet's data.

           packet dump <packet variable> displays an hexadecimal dump (on standard output) of the
           packet's data.

           packet ts <packet variable> will return a timeval variable that corresponds to the
           timestamp associated with the specified packet variable.

           packet tdelta <packet variable 1> <packet variable 2> calculates the time delta
           between the timestamp associated with <packet variable 1> and the timestamp associated
           with <packet variable 2>.

       pdu <new | delete | dup | append | count | build | list> <args>
           The pdu command is used to manage variables of type pdu (Protocol Data Unit.)

           pdu new <PDU definition> will create and return a new pdu variable. The PDU definition
           is the same as used in other Network Expect commands like send_network and
           send_expect.

           pdu delete <pdu variable> will delete a pdu variable.

           pdu dup <pdu variable> will duplicate a pdu variable.

           pdu append <pdu variable 1> <pdu variable 2> will append the pdu variable pdu variable
           2 to the pdu variable pdu variable 1. The result is pdu variable 1.

           pdu count <pdu variable> returns the number of packets that would be generated if that
           PDU were to be sent using the send_network command, for example. The number of packets
           depends on the numeric specifications used in the definition of the PDU.

           pdu build <pdu variable> builds the specified pdu variable and returns a variable of
           type packet.

           pdu list displays the list of PDUs that Network Expect knows about, i.e. the PDUs that
           can be created via certain Network Expect commands like send_network, send_expect, and
           pdu new.

       random [x:y | number x:y | ip [a.b.c.d/nn | a.b.c.d:e.f.g.h] | mac]
           The random command can be used to obtain a variety of random objects. Current
           supported objects are numbers, IPv4 addresses, and MAC addresses. It is possible to
           obtain a random number or IP address from within a range. In the case of numbers the
           range is specified using the notation x:y. In the case of IP addresses the range can
           be specified using the IP address/netmask bits notation, or using the a.b.c.d:e.f.g.h
           notation. If no object is specified then a random number is returned.

       send_expect [-i <listener ID>] [-o <speaker ID>] [-timeout <timeout>] [-n <number of
       tries>] <PDU definition>
           This command sends a number of packets to a target or list of targets and then waits
           for responses. After responses are received, the command matches sent packets with
           received packets. This command was inspired by the sr() family of commands in Scapy,
           the packet manipulation tool by Philippe Biondi.

           The -i flag specifies what listener to use to read responses. It is possible to
           specify multiple listeners by using this option multiple times.

           The -o flag specifies what speaker to use when injecting the stimulus.

           -timeout specifies how long to wait, after all packets have been sent, for answers to
           the injected stimulus. The timeout is specified in seconds and the default is 1
           second.

           -n specifies how many times to retry sending the stimulus if not all sent packets have
           a corresponding received answer.

           The definition of the PDU to send is the same as it used in the send_network command.

           The send_expect command creates three lists: the list of sent packets and the
           corresponding list of matching answers, and the list of unanswered packets. A script
           can then use these lists, decode packets, and present some useful information. For
           example, the following code snippet sends ICMP echo requests to all hosts in a network
           a displays which hosts replied:

               set network 192.168.1.1-192.168.1.254

               # Spawn a listener. We don't really have to specify a filter,
               # like in "spawn_network {icmp[icmptype] == icmp-echoreply}"
               # because the send_expect command will intelligently match
               # injected stimulus (ICMP echo requests) with received
               # answers (ICMP echo replies). A filter means less work for
               # the send_expect command, but other than that it adds nothing.
               spawn_network

               send_expect -n 2 -4 -D $network -icmp-echo random:random \
                   -payload "12345678901234567890" -delay .001

               puts "\n[llength $_(received)] hosts sent echo-replies back:\n"

               foreach r $_(received) s $_(sent) {
                   packet decode r
                   puts [format "$pdu(1,tot_len) bytes from $ip(src): ttl=$ip(ttl) time=%.3f ms" [expr [packet tdelta r s]*1000] ]
               }

       send_network [options] <PDU definition>
           This command allows the creation custom TCP/IP packets based on packet definitions
           provided by the user through command-line arguments passed to the program, through a
           command file specified in the command-line, or through a mix of these two methods.
           send_network refers to instances of protocols in the TCP/IP protocol suite as protocol
           data units, or PDUs for short. A protocol data unit always has a header (think of the
           IP version 4 header, or the TCP header), may or may not have options (think of the TCP
           options, or IP version 6 extension headers), and may or may not have a payload. Due to
           the extensive use of encapsulation in the TCP/IP protocol suite, the payload of a PDU
           can be another payload. For example, an Ethernet frame can have as its payload an IP
           version 4 packet, which in itself is another PDU. Then this IP version 4 packet can
           have as its payload a TCP segment, which is another PDU, and so on.

           When defining PDUs that send_network will create you start by creating the definitions
           for PDUs that are closer to the physical layer, and then move up the protocol stack
           until you reach, in some cases, and if that is what you want, the application layer.
           To implement this approach through a command-line interface (CLI) you start by
           entering the lower-level PDUs closer to the beginning of the command-line, or, if you
           are reading your packet definitions from a file, by entering definitions for
           lower-level PDUs at the beginning of the file. After you have defined a certain PDU
           you cannot define another PDU that is lower than the previous in the protocol stack.
           For example, you cannot define a TCP segment and then create an Ethernet frame as the
           segment's payload, just because that does not make sense (defining a TCP segment and
           then a BGP message does make sense, for example.) For this reason, order does matter
           in the command-line (or in the file, if defining PDUs in a file) when creating the
           PDUs.

       sleep <seconds>
           causes the script to sleep for the given number of seconds.  seconds may be a decimal
           number. Interrupts are processed while Network Expect sleeps.

       spawn_network [-nolistener] [-fullspeed] [-info] [-i <input interface>] [-o <output
       interface>] [-r <input PCAP file>] [-p] [-s <snaplen>] [-w <output PCAP file>] [-hexdump]
       [-stdout] [-4] [-6] [<PCAP filter>]
           The spawn_network command is used to find information about existing listeners and
           speakers or to create network speakers and network listeners.

           To find information about existing network listeners and speakers the spawn_network
           command needs to be invoked with only the -info option.

           Listeners are created by using the options -i or -r.  -i specifies an interface to
           listen for traffic on, and -r specifies the use of a PCAP file for reading instead of
           reading live traffic from an interface. In both cases, an optional PCAP filter can be
           specified to limit the type of traffic that will be read. If -i is not used then
           Network Expect will try to find a suitable interface.  -fullspeed causes reading from
           a PCAP file at full speed, without preserving the inter-packet delay present in the
           savefile. If this option is not specified then the inter-packet delay present in the
           savefile will not be preserved.

           Speakers are created using one of -o, -w, hexdump, stdout, -4, or -6.  -o specifies
           the use of an interface for injecting traffic into the network. This implies the use
           of layer 2 injection in which the Ethernet header is specified by the user.  -w
           specifies that all traffic will be sent to the PCAP file PCAP file. This option
           requires the use of layer 2 injection, i.e. the Ethernet header must be included.
           -hexdump specifies that all packets be sent to standard output in hexadecimal format.
           -stdout causes all packets to be sent to standard output in raw format. The -4 and -6
           options specify the creation of layer 3 speakers to inject IPv4 and IPv6 traffic
           respectively. In this case all routing decisions are performed by the kernel.

           The -p and -s options are only meaningful for listener creation.  -p specifies that
           the interface be not put in promiscuous mode when creating a listener that will listen
           on an interface.  -s specifies the snapshot length of captured packets. These two
           options are equivalent to the tcpdump(8) options of the same names.

           Note that if no options to create a speaker are specified, i.e.  -o, -w, hexdump,
           stdout, -4, or -6, the default action is to only create a listener. If only a speaker
           is desired one of the options to create a speaker must be specified and the -nolistner
           option must be used.

           As an example, the follow command creates a listener on interface eth0 for ARP
           requests for the MAC address of host 192.168.1.1:

               spawn_network -i eth0 host 192.168.1.1 and {arp[6:2]} == 1

           Note that curly braces are necessary around "arp[6:2]" because brackets have special
           meaning in Tcl.

       system <system command> [<args>]
           The system command allows to run arbitrary system commands from within a Network
           Expect script.

           Please note that this command does no input validation at all, which means that it is
           very insecure. For example "system {ls;/bin/sh}" will give you a shell. If nexp is run
           as roon then the shell will be a root shell.

           The exec command in the standard Tcl distribution is a much better alternative to the
           Network Expect system command. Please see the Tcl documentation for the exec command
           for additional information.

       timeval new | delta <args>
           The timeval command allows to manage variables of type timeval.

           timeval new; returns a timeval variable that corresponds to the current system time.

           timeval tdelta <timeval variable 1> <timeval variable 2> calculates the time delta
           between the timeval variable 2 and timeval variable 1.

       txdelta <speaker ID>
           Every time a packet is sent, the time the packet was sent is saved to the network
           speaker that was used to send that packet. The txdelta (short for "transmission
           delta") command returns the number of seconds that have elapsed since the last packet
           that was sent via the specified speaker ID.

           The following example provides the foundation for a very simple ping program, and
           shows how the txdelta command can be used:

               for {set id 0; set seq 0} {1} {incr seq} {
                   send_network -4 -D $target -icmp-echo $id:$seq -payload "12345678901234567890"

                   expect_network -timeout 1 {$icmp(type) == 0 && $icmp(id) == $id} {
                       puts [format "$pdu(2,tot_len) bytes from $ip(src): icmp_seq=$seq ttl=$ip(ttl) time=%.3f ms" [expr [txdelta ip]*1000 ] ]
                       sleep [expr 1.0 - [txdelta ip] ]
                   }
               }

SPECIAL VARIABLES

       Special variables.

EXAMPLES

       The examples directory in the Network Expect distribution contains plenty of examples that
       should provide a very good idea of how to use Network Expect. A few selected examples have
       been selected for this manual page.

        1. The following code snippet performs a TCP three-way handshake. Everything is done by
           hand, which allows to play with TCP initial sequence numbers (ISNs), window sizes,
           etc. The code is a bit more complex that necessary because an effort is made to handle
           error coditions (timeout, remote host not listening on the destination port, strange
           combination of TCP flags received in response to our initial SYN.)

               # Some useful constants
               set SYN 0x02
               set RST 0x04
               set ACK 0x10

               set retries 3
               set isn [random]
               set myip 192.168.1.2
               set target 192.168.1.1
               set sport [random 20000:65535]
               set dport 21
               set window 4096

               # Spawn a listener for TCP segments coming from the FTP server to us
               spawn_network -i $interface "tcp and src host $target and dst host $myip and src port $dport and dst port $sport"

               # Send TCP SYN
               send_network ip(src = $myip, dst = $target)/ \
                            tcp(src = $sport, dst = $dport, window = $window, \
                                syn, seq = $isn, ack-seq = 0)

               # Wait for response from the server
               expect_network {$tcp(flags) == ($SYN | $ACK)} {
                   # Got a SYN+ACK so we need to send the final segment of the
                   # 3-way HS
                   send_network ip(dst = $myip, dst = $target)/ \
                                tcp(dst = $tcp(dstport), dst = $tcp(srcport), \
                                    window = $window, ack, seq = $tcp(ack), \
                                    ack-seq = [expr $tcp(seq) + 1])
               } {$tcp(flags) & $RST} {
                   puts "Connection refused"
                   exit 1
               } {1} {
                   # Any other weird combination of TCP flags we respond to
                   # with a RST
                   send_network ip(src = $myip, dst = $target)/ \
                                tcp(src = $tcp(dstport), dst = $tcp(srcport), \
                                    rst)
                   exit 1
               } timeout {
                   # Our SYN got lost in transit or it was filtered - perform
                   # exponential backoff and retransmit the SYN...
                   if {$retries > 0} {
                       incr retries -1
                       set timeout [expr $timeout*2]
                       puts "SYN timeout, increasing timeout to $timeout"
                       send_network ip(src = $myip, dst =  $target)/ \
                                    tcp(src = $sport, dst = $dport, \
                                        window = $window, syn, seq = $isn, \
                                        ack-seq = 0)
                       nexp_continue
                   } else {
                       puts "Connection timed out"
                       exit 1
                   }
               }

               # TCP connection has been established. Now do something...

        2. This illustrates how to create a phantom host on the network that can respond to ICMP
           echo requests, and therefore, to ARP requests as well.

               set interface eth0
               set myip 192.168.1.1
               set mymac [random mac]

               # Spawn a listener for ARP requests
               spawn_network -i $interface host $myip and {arp[6:2]} == 1
               set arpl $listener_id

               # Spawn a listener for ICMP messages sent to us
               spawn_network -i $interface icmp and dst host $myip
               set icmpl $listener_id

               expect_network_background -i $arpl {1} {
                   # Received an ARP request, send ARP reply
                   send_network -o $interface \
                       ether(src = $mymac, dst = $arp(sha) )/ \
                       arp-reply(tha = $arp(sha), tip = $arp(sip), \
                                 sha = $mymac, sip = $myip)
                   nexp_continue
               } -i $icmpl {$icmp(type) == 8} {
                   # Received ICMP echo request, send echo reply
                   send_network -o ip \
                       ip(src = $myip, dst = $ip(src) )/ \
                       icmp-echoreply(id =  $icmp(id), seq = $icmp(seq) )/ \
                       raw($raw)
                   nexp_continue
               }

        3. This example how to create a very simple traceroute program that uses TCP probes to
           port 80 of the target host. It uses the send_expect command.

               set target "www.example.com"
               set ttlrange "1:30"
               set interface [outif $target]

               # Spawn a listener. We don't really have to specify a filter because the
               # send_expect command will intelligently match injected stimulus with
               # received answers.
               spawn_network -i $interface

               send_expect -tries 2  -delay 0.001 \
                   ip(id = random, dst = $target, ttl = $ttlrange)/ \
                   tcp(src = random, dst = 80, syn)

               foreach r $_(received) s $_(sent) {
                   packet decode r
                   set source $ip(src)
                   set pdu_type $pdu(1,type)

                   packet decode s

                   puts [format "$ip(ttl) $source %.3f ms $pdu_type" [expr [packet tdelta r s]*1000] ]
               }

        4. This shows how to perform an ARP scan using regular send_network and expect_network
           commands:

               set interface eth0
               set network "$iface($interface,ip)/$iface($interface,netmask)"

               set arprequest [pdu new -o $interface
                   ether(dst = BROADCAST)/ \
                   arp-request(tha = BROADCAST, tip = $network, \
                               sha = $iface($interface,hw_addr), \
                               sip = $iface($interface,ip) ) ]

               # Spawn a listener for ARP replies
               spawn_network -i $interface {arp[6:2]} == 2

               for {set i 0} {$i < [pdu count arprequest]} {incr i} {
                   # Send ARP request
                   send_network -count 1 arprequest

                   # Read ARP reply
                   expect_network -timeout .05 {1} {
                       puts "$arp(sip) is at $arp(sha)"
                   }
               }

        5. This example shows how to do an ARP scan but in a more efficient manner using the
           send_expect command:

               set interface eth0
               set network "$iface($interface,ip)/$iface($interface,netmask)"

               # Spawn a listener for ARP replies
               spawn_network -i $interface {arp[6:2]} == 2

               send_expect -o $interface -delay 0.001 -tries 2 \
                   ether(dst = BROADCAST)/ \
                   arp-request(tha = BROADCAST, tip = $network, \
                            sha = $iface($interface,hw_addr),
                               sip = $iface($interface,ip) )

               puts "\nFound [llength $_(received)] hosts alive:\n"

               foreach r $_(received) {
                   packet decode r
                   puts "$arp(sip) is at $arp(sha)"
               }

BUGS

       Network Expect does not run very well under the Solaris operating system because in that
       operating system select() does not seem to work well with packet capture file descriptors
       (select() returns when there is no data ready to be read.)

       Network Expect does not work at all in Microsoft Windows because select() does not work at
       all with packet capture file descriptors (pcap_get_selectable_fd() does not exist under
       Microsoft Windows.)

       Error-checking is almost non-existant.

       These isn't input validation for the numeric specifications.

       The parser of PDU definitions (and therefore the number of tokens that the parser handles)
       has become a big, wild beast. It's very easy to add new tokens and PDU definitions are
       elegant and pretty, but the parser is huge. Guess can't have everything.

VERSION

       This man page is correct for version 1.0 of Network Expect.

SEE ALSO

       nexp-numspec(1), nexp-payload(1), nexp-ether(5), nexp-gre(5), nexp-ip(5), nexp-mpls(5),
       expect(1)

AUTHOR

       Network Expect was written by Eloy Paris <peloy@netexpect.org>. However, Network Expect
       borrows ideas from lots of Open Source tools like Nemesis, Packit, hping, Expect, and
       Scapy. The Network Expect author is indebted to the authors of these tools for their
       contribution.

       This man page was written by Eloy Paris although it borrows heavily from Expect's manual
       page.

[FIXME: source]                          29 November 2006                                 NEXP(1)