1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
#!/usr/local/bin/nexp
#
# Example of creating and sending an ICMP echo request with a large ICMP
# payload. This example shows two things:
#
# 1. How to create a large PDU that later gets used as payload for
# another PDU. Specifically, we create a large ICMP echo request
# that will later be delivered by IP packets. The ICMP checksum
# is calculated automatically and transparently.
#
# 2. How to send a large IP payload, greater than the interface's MTU,
# that then requires to be fragmented. We handle this in a special
# Tcl procedure created just for this task.
#
# peloy@netexpect.org
# Mon Mar 22 22:31:20 EDT 2010
#
if {$argc != 1} {
puts "Usage: $argv0 <hostname or IP address>"
exit 1
}
# Sends data via IP packets. Fragments data if needed.
proc fragmented_send {pkt dst proto} {
upvar $pkt p
global iface
set mtu $iface([outif $dst],mtu)
set adjusted_mtu [expr $mtu - 20] ;# "20" accounts for IP header
set id [random]
for {set remaining [packet length p]; set fragoff 0} \
{$remaining > $adjusted_mtu} \
{incr remaining -$adjusted_mtu; incr fragoff $adjusted_mtu} {
# Send fragment. Note that the MF flag is set.
send_network ip(dst = '$dst', mf, id = $id, \
fragoff=[expr $fragoff >> 3], proto = $proto)/ \
data(data = '[packet data p ${fragoff}l$adjusted_mtu]')
}
# Send final fragment. Note that the MF flag is not set.
send_network ip(dst = '$dst', id = $id, \
fragoff=[expr $fragoff >> 3], proto = $proto)/ \
data(data = '[packet data p ${fragoff}:]')
}
set target [lindex $argv 0]
set datalen 15000 ;# size of ICMP payload
# Define the ICMP PDU
set icmppdu [pdu new icmp-echo(seq = 1073)/data(data = 'random:$datalen')]
# Build the ICMP PDU
set icmp [pdu build icmppdu]
# Transmit ICMP PDU
fragmented_send icmp $target 1
|