Frequently Asked Questions



"What is Network Expect?" questions
    What is ''Network Expect''?
    What is it good for?
    How does Network Expect compare to Scapy?
    What platforms does it run on?
    Can Network Expect send packets from the shell's CLI?
    Can Network Expect be used as a Tcl package?
    Correlating the $pdu(n,*) and the $<protocol>(*) variables
    Can Network Expect handle IP fragmentation/TCP segmentation?
Developer help

“What is Network Expect?” questions

What is “Network Expect”?

Network Expect is a framework for managing network packets, including packet crafting, injection, and reception. The framework uses Tcl, which 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 send by the application and take decisions accordingly. In Network Expect, 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.

What is it good for?

NetworkExpect can be useful for recreating situations that trigger a problem (bug), for replaying traffic, for writing proof-of-concept protocols and tools, for simulating Denial-of-Service attacks, and, in general, for situations that require injecting and processing network traffic at a very low level, i.e. traffic that requires transmitting and receiving invalid packets, traffic that requires setting specific header fields to specific values (e.g. TCP sequence numbers, TCP and IP flags, etc.)

How does Network Expect compare to Scapy?

I am not a heavy Scapy user so what follows may not be totally accurate when it comes to Scapy. If you see inaccuracies please feel free to fix them by editing the text directly:

Scapy is a great network tool. Of all the network tools out there, I personally view Scapy as NetworkExpect’s main competitor. The other tools only do some of the things that Scapy can do, and I think Scapy was a breakthrough in the field. Its design is brilliant, and the functionality is absolutely fantastic.

NetworkExpect and Scapy ( share some similarities. Both tools allow to craft network packets with great flexibility, and then inject packets at either layer 2 or 3. Both tools also allow to process incoming network traffic and script decisions, based on received traffic, via a high level language.

Scapy provides two functions for packet injection, sendp() (layer 2 injection) and send() (layer 3 injection.) NetworkExpect has a single command for packet injection, the send_network command. This command can do both layer 2 and layer 3 injection, depending on the definition of the packet (via command-line options to the command.)

Defining packets in Scapy is done in a very similar way to how it is done in NetworkExpect. For instance, in Scapy, an ICMP echo request is built and sent in the following manner:

send(IP(dst=“”)/ICMP(id=123, seq=456)/Raw(“1234567890”) )

In NetworkExpect, the same thing is accomplished with:

send_network ip(dst = = 123, seq = 456)/data(data=‘1234567890’)

Both Scapy and NetworkExpect allow to read and write packets from and to files in PCAP format. Scapy uses two functions, rdpcap() and wrpcap(), for reading and writing PCAP files. NetworkExpect does not have special functions to accomplish the same thing. Instead, the source (for reading packets) and the destination (for injecting packets) are defined when listeners and speakers are created, which is done via the spawn_network command. Then, reading packets is done via regular expect_network commands, and injecting packets is done via regular send_network commands.

Scapy has a very powerful family of functions called the “send and receive” functions. The Scapy documentation calls this family of functions the “heart of Scapy”. These commands (sr(), sr1(), srp(), and srp1()) inject some stimulus and then process responses to that stimulus to match sent and received packets. These functions allow to build network tools in a very efficient manner. NetworkExpect borrowed the same concepts from Scapy, and provides the same functionality in the form of the send_expect command. In fact, the algorithms for the send_expect NetworkExpect command are the same as the ones in Scapy, just written in a different programming language and in different implementations. Results from the “sr()” and “send_expect” commands are the same (list of packets sent with matching responses and list of unanswered packets) but the way they must be handled is different due to differences in the scripted language each tool uses (Python versus Tcl.)

The “send/expect” philosophy of NetworkExpect is something that I think makes NetworkExpect attractive, and it is something that Scapy doesn’t have, at least not as the same concept.

Scapy has been around for a long time and I believe it has more features. It definitely has knowledge about a lot more PDU types. There are some Scapy features (like the graphing stuff) that I haven’t even started to think about for NetworkExpect. Scapy also has an army of collaborators fixing bugs and adding new features. NetworkExpect on the other hand just saw the public light as an open source project very recently, and is currently a one-man show.

Scapy uses Python ( as its scripting language and NetworkExpect uses Tcl ( To seriously use Scapy, and all features it has to offer, knowledge of Python is needed. Obviously, the same thing must be said about NetworkExpect and its reliance on Tcl. Python is a more modern and powerful language than Tcl. I personally find Tcl easier to master than Python, perhaps because Tcl is a simpler language.

Scapy is written in Python and NetworkExpect in C. This should (“should” because I haven’t made any performance comparisons) make NetworkExpect a bit faster than Scapy. While performance is not usually a problem when building prototypes of network tools, I believe there are cases where you need to pump out packets as fast as possible. NetworkExpect should be efficient and capable of melting your network when injecting traffic.

Due to the languages that NetworkExpect and Scapy are written on, the entry barrier to NetworkExpect hacking (to extend, enhance, modify and/or maintain the tool) may be higher than that of Scapy. C is a great language, but it is a very low level language (it’s almost like a very good macro-assembler) that takes time to master. Python on the other hand is supposed to be an easier language to learn.

Whether to choose Scapy or NetworkExpect will (hopefully) be a matter of personal preference (assuming feature parity.) People that know Tcl and Expect may find NetworkExpect very appealing. People that know Python will find Scapy more appealing. In any case, competition is a good thing.


What platforms does it run on?

I have built and successfully run NetworkExpect on Linux, FreeBSD, OpenBSD, and MacOS X. I have also built NetworkExpect on Solaris 10 but Solaris seems to have some issues when it comes to using select() on STREAMS file descriptors that I still have not been able to figure out.

See the PortabilityPage for tips and information on how to build NetworkExpect for your platform.


Can Network Expect send packets from the shell’s CLI?

Sure. The NetworkExpect executable (nexp) has a “-c” CLI switch that allows to specify NetworkExpect commands to run before a script is run. This feature can be used to craft and send packets from the shell’s prompt. For instance, to send an ICMP echo request from the shell prompt you can use:

shell# nexp -c “send_network ip(dst - = 123, seq = 456)/data(data=‘1234567890’)”

You can even write a short wrapper for this so you only have to type the minimum necessary:

exec nexp -c “send_network $*”

You would use this little wrapper like:

shell# /usr/local/bin/ “ip(dst = = 123, seq = 456)/data(data=‘1234567890’)”

Additionally, starting with version 0.16 of NetworkExpect there is a little utility called tgn (traffic generator) which allows to generate traffic directly from the CLI. For example:

shell# tgn “ip(src =, dst = <,>,ttl = <1, 2>)/”
“tcp(src = ‘random’, dst = 22..25, window = 16384,syn, seq = ‘random’, ack-seq = 0)”

This eliminates the need to create a wrapper to call nexp with the -c switch.

Can Network Expect be used as a Tcl package?

Today NetworkExpect cannot be used as an external package that can be invoked from a script via:

package require NetExpect

This feature is in the list of planned enhancements.

Correlating the $pdu(n,) and the $() variables

Q: We have a bunch of various info in “$pdu(n,)” where n is a number that indicates the PDU layer. But then we also have a bunch of information in “$()“, like $tcp(seq), $ip(id), $ip(ttl), etc. Is there a way to correlate those two from a script; is there a way to access these variables without Tcl generating an exception of the variable does not exist?

A: We have “$pdu(list)” which tells us, for example, “the first layer is ether, the second layer is ip, the third layer is tcp, the fourth layer is raw”.

However, the most important thing is that users should know at what layer they are working, and therefore, use the appropriate “$(*)” variable within the right context.

For instance, if the user has “spawn_network -i eth0 tcp”, then the user knows that an expect_network that uses that listener will have access to “tcp()“. In that expect_network the user can’t use “udp()” because, obviously, that listener will never return UDP datagrams (it is possible to use udp(*) but they would have to be from a different listener, which was read from in another expect_network statement.)

In cases where a listener with no filter is being used and the user has no clue about what type of PDU it is being dealt with, it is possible to prevent the script from aborting by using something like:

expect_network {info exists tcp} {… use $tcp(*) variables …}

Another option is to use Tcl’s catch command:

catch expect_network {$arp(type) == 2} {do something with arp(*)}

And another option (which is probably the best) is to use the “pdu(list)” variable that I mentioned before. For example:

spawn_network -i eth0 ;# No filter, will receive all types of traffic

expect_network {[lindex $pdu(list) 1] == “ip”} { if [lindex $pdu(list) 2] == “tcp”] { … use $tcp() … } elseif [lindex $pdu(list) 2] == “udp”] { … use $udp() … } else { # ignore non-TCP and non-UDP traffic } } {[lindex $pdu(list) 1] == “arp”} { … use $arp(*) … }

Can Network Expect handle IP fragmentation/TCP segmentation?

On the sending side no, Network Expect does not have built-in capabilities to handle IP fragmentation or TCP segmentation. When generating traffic, everything is stateless, which means no fragmentation or segmentation. It is your responsibility to ensure that whatever you inject into the wire does not exceed the outgoing interface’s maximum transmission unit (MTU); otherwise your PDU will not make it to the wire. Handling IP fragmentation is easy, though, and an example of simple implementation in Tcl exists. Handling TCP segmentation is a harder task since it basically means writing a basic TCP stack, and this has not been done.

On the receiving side, IP fragmentation and TCP segmentation, or rather their re-assembly process, is handled very nicely by libwireshark, which is what Network Expect uses for dissection of network traffic.

Developer help

I’m aware of the need to provide documentation on how to extend NetworkExpect. It’ll come at some point…