The send-expect command
=======================

send-expect -o <speaker> -4 -D cisco.com -icmp-echo 0:0

Brief algorithm description
---------------------------

- PDU defined via parameters to the send-expect command is built

- After the PDU is built, packets are generated by calling pdu_build().
This will produce several packets that later will be sent via
pdu_output().

- Once we have the raw data of packets to be sent, a hash of each packet
is generated. We store this hash in a data structure for later retrieval.

- We now send the packets. The right speaker must be used in the send-expect
command, of course.

- We then wait for answers. Every time we receive a packet we:

  * calculate hash of the packet

  * if the hash exists in the data structure that keeps hashes of the
  the packets we sent we:

    + call the packet's answers() function

    + if answers() returns true then we have matched a packet sent with
    a received packet. We then:

      o add the packet to the list of answered packets and print '*' to
      stdout if verbose is turned on.

      o if we're not matching multiple times we remove the hash of the
      packet just received from the data structure that keeps hashes of the
      the packets we sent

  * if there are no unanswered packets then we're done

Hashes
------

Ethernet:

hash = ethertype + hash(payload)
len(hash) = 2 + len(hash(payload) )

IP:

if payload is ICMP and ICMP type is ICMP_DEST_UNREACH, ICMP_SOURCE_QUENCH,
    ICMP_REDIRECT, ICMP_TIME_EXCEEDED or ICMP_PARAMETERPROB then
    hash is that of the embedded IP packet
else
    if checking IP src && checking IP addr
      hash = (src IP ^ dst IP) + IP proto + hash(payload)
      len(hash) = 5 + len(hash(payload) )
    else
      hash = IP proto + hash(payload)
      len(hash) = 1 + len(hash(payload) )

ICMP:

hash = id + seq + hash(payload)
len(hash) = 4 + len(hash(payload) )

Return value from the send-expect command
-----------------------------------------

The send-expect command returns a list of sent packets and their
responses and a list of unanswered packets.

# For multiple answers for each packet
foreach s ts rlist trlist {$_(sent) $_(tsent) $_(received) $_(treceived)} {
    foreach r tr {$rlist $trlist} {
	packet decode r
	puts "$arp(sip) is at $arp(sha)"
	puts "[packet summary s] -> [packet summary r]"
    }
}

# For a single answer for each packet
foreach s r {$_(sent) $_(received)} {
    packet decode r
    puts "$arp(sip) is at $arp(sha)"
    puts "[packet summary s] -> [packet summary r]"
}

-or-

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