#######################################
#sample for icmp traceroute
#######################################
from pktbuilder import *
import jarray
import random
import fpformat
import time
import java.io.IOException
def createEchoRequest(srcMac, dstMac, srcIp, dstIp, dataBytes):
"""ICMP Echo-Request Packet Creation
"""
#protocol stack is ("Ethernet", "IPv4", "ICMP")
packet = Packet(["Ethernet", "IPv4", "ICMP"])
packet.setTextValue("Ethernet", "destination_address", dstMac)
packet.setTextValue("Ethernet", "source_address", srcMac)
packet.setIntValue("Ethernet", "ether_type", 0x0800)
packet.setIntValue("IPv4", "identification", random.randrange(1, 0xFFFF))
packet.setIntValue("IPv4", "protocol", 0x01)
packet.setTextValue("IPv4", "source_address", srcIp)
packet.setTextValue("IPv4", "destination_address", dstIp)
packet.select("ICMP", "icmp_root", "echo_request")
data = range(0, dataBytes)
packet.setByteArrayValue("ICMP", "data", data)
return packet
#socket factory creation
factory = PcapSocketFactory()
#get all device(network adapter) name in sequence
devices = factory.getDevices()
#print "devices:",devices
#local machine address
LOCAL_MAC = "00:16:D4:17:25:C4"
#local machine IP address
LOCAL_IP = "192.168.11.2"
#create socket
socket = factory.createSocket()
#set socket parameter. "devices[1]" is selecting the second device.
socket.setPcapSetting(devices[1],
PcapSocket.DEFAULT_SNAPLEN,
PcapSocket.DEFAULT_PROMISC,
5)
#target IP address(www.baidu.com)
dstIp = "220.181.38.4"
#gateway mac address
gatewayMac = "00:16:01:15:a4:88"
#data count
dataBytes = 10
#maxium passed router
maxHops = 40
#buffer creation
buffer = jarray.zeros(1600, "b")
#Packet Serializer object creation
serializer = PacketSerializer()
#open the socket
socket.open()
#receiving filter setting
socket.setFilter("ip dst " + LOCAL_IP + " and icmp")
#create the ID for ICMP
icmpId = random.randrange(1, 0xFFFF)
#if reached the destination
reachedDst = 0
for i in xrange(1, maxHops) :
#sequence NO. of ICMP
seqNo = i
#field of TTL in IP, increase 1 each time
ttl = i
#ICMP Echo-Request packet creation
packet = createEchoRequest(LOCAL_MAC, gatewayMac, LOCAL_IP,
dstIp, dataBytes)
#Set the field of id and sequence for protocol of ICMP.
packet.setIntValue("ICMP", "identifier", icmpId)
packet.setIntValue("ICMP", "sequence_number", seqNo)
packet.setIntValue("IPv4", "ttl", ttl)
#AutoUtil().printPacket(packet)
#Create the raw sending data.With encoding the packet.
rawData = serializer.encode(packet)
#Sending
startTime = time.time()
socket.write(rawData, 0, len(rawData))
#Receiving
try :
rlen = socket.read(buffer, 0, len(buffer))
#ignore the timeout of socket
except java.io.IOException :
print "Request timeout"
continue
newPacket = serializer.decodeAuto(buffer, 0, rlen, "Ethernet")
# AutoUtil().printPacket(newPacket)
if newPacket.contains("ICMP", "echo_reply") :
#Check the integration of Packet.The id received must be same as the
#ID which sent.
recvIcmpId = newPacket.getIntValue("ICMP", "identifier")
recvSeqNo = newPacket.getIntValue("ICMP", "sequence_number")
if (recvIcmpId != icmpId or recvSeqNo != seqNo):
print "Invalid reply with id=", recvIcmpId, " and seq no=", seqNo
reachedDst = 1
tempIp = newPacket.getTextValue("IPv4", "source_address")
ttl = newPacket.getIntValue("IPv4", "ttl")
print i, " from ", tempIp, " time<=", \
fpformat.fix(time.time()-startTime, 4), "(s)", " TTL=", ttl
if reachedDst:
break
#print statistics
print "Traceroute complete. "
if reachedDst :
print dstIp , " is reached."
else :
print dstIp , " is not reached."
#close socket
socket.close()