# -*- coding: ISO-8859-1 -*-
import scapy, os, optparse, threading, time
from scapy import *
from pyx import *



def usage():

	global options
	parser = optparse.OptionParser("usage: %prog [options] arg1 arg2")
	parser.add_option("-S", "--SrvDNS", dest="SrvDns",help="Set DNS Serveur")
	parser.add_option("-N", "--Number", dest="Number",default="100",help="Set number of request")
	parser.add_option("-D", "--Domain", dest="Domain",help="Set domain name")
	parser.add_option("-A", "--ASrcHost", dest="SrcHost",help="Set SrcHost")
	(options, args) = parser.parse_args()




class sniffer(threading.Thread):

	def __init__(self,srvdns,number,srchost):
		threading.Thread.__init__(self)
		self.srvdns = srvdns
		self.number = int(number)
		self.srchost = srchost
	
	def run(self):
		print "Thread start ; )"
		self.sniff()
		print "Parse result ..."
		time.sleep(1)
		self.numberline("transid.dat","transid.tmp")
		self.numberline("portsrc.dat","portsrc.tmp")
		self.genegraph("transid.tmp","Nb of Packet","Transaction ID")
		self.genegraph("portsrc.tmp","Nb of Packet","Port Src")
		self.genegraph("portid.tmp","Transaction ID","Port Src")
		
	def sniff(self):
		print "Sniffing enable ..."
		global fid, fport, fportid
		fid = open('transid.dat','w')
		fport = open('portsrc.dat','w')
		fportid = open('portid.tmp','w')
		self.filter = "not arp and (src host "+self.srchost+" and udp dst port 53)"
		a=scapy.sniff(count=self.number,filter=self.filter,prn = lambda x: self.backupidtrans(x))
		print "Sniffing Stop"
		fid.close()
		fport.close()
		fportid.close()
		
	def backupidtrans(self,pkt):
		#print pkt.summary
		ipsrc = pkt.payload.src
		portsrc = pkt.payload.sport
		transid = pkt.payload.payload.payload.id
		querydns = pkt.payload.payload.payload.qd
		querytxt = querydns.qname
		print "ipsrc:"+ipsrc
		print "portsrc:"+str(portsrc)
		print "transid:"+str(transid)
		print "querydns:"+str(querytxt)
		query=scapy.DNSQR(qname=str(querytxt),qtype='A',qclass='IN')
		response=scapy.DNSRR(rrname=str(querytxt), type='A', rclass='IN', ttl=1847, rdata='127.0.0.1') 
		scapy.send(IP(src='172.16.160.135',dst=ipsrc)/UDP(sport=53,dport=portsrc)/DNS(id=transid,qr=1L,opcode="QUERY",aa=0L,tc=0L,rd=1L,ra=1L,z=0L,rcode="ok",qdcount=1,ancount=1,nscount=0,arcount=0,qd=query,an=response,ns=0, ar=0 ))
		fid.write(str(transid)+"\n")
		fport.write(str(portsrc)+"\n")
		fportid.write(str(transid)+"\t"+str(portsrc)+"\n")
		
	def genegraph(self,file,namex,namey):
		self.file = file
		self.prefix = self.file.replace(".tmp", ".pdf")
		self.namey = namey
		self.namex = namex
		if self.file=="portsrc.tmp" or self.file=="portid.tmp":
			g = graph.graphxy(width=20, ratio=4./3, key=graph.key.key(),x=graph.axis.linear(title=namex),y=graph.axis.linear(min=1,max=65535,title=namey))
		else:
			g = graph.graphxy(width=20, ratio=4./3, key=graph.key.key(),x=graph.axis.linear(title=namex),y=graph.axis.linear(title=namey))
		g.plot(graph.data.file(self.file, x=1, y=2, title=self.namex),styles=[graph.style.symbol(symbolattrs=[color.rgb.red])])
		g.writePDFfile(self.prefix)
		os.remove(self.file)
		print self.prefix+" generated !"

	def numberline(self,fileread,filewrite):
		self.fileread = fileread
		self.filewrite = filewrite
		rf = open(self.fileread,'r')
		wf = open(self.filewrite,'w')
		comp = 1
		for line in rf:
			wf.write(str(comp)+"\t"+line)
			comp=comp+1
		rf.close()
		wf.close()
		os.remove(self.fileread)

class sender(threading.Thread):
	def __init__(self,srvdns,domain,number):
		print "init sender..."
		threading.Thread.__init__(self)
		self.srvdns = srvdns
		self.domain = domain
		self.number = int(number)
		print self.number

	def run(self):
		self.send()
		
	def send(self):
		i = 0
		while i < self.number:
			self.numberand = RandLong()
			self.queryname = str(self.numberand)+"."+self.domain
			#print self.queryname
			query=scapy.DNSQR(qname=self.queryname,qtype='A',qclass='IN')
			#print "Send 1 dns request packet"
			time.sleep(0.1)
			print self.srvdns
			scapy.send(IP(dst=self.srvdns)/UDP(sport=RandShort(),dport=53)/DNS(id=RandShort(),qr=0L,opcode="QUERY",aa=0L,tc=0L,rd=1L,ra=0L,z=0L,rcode="ok",qdcount=1,ancount=0,nscount=0,arcount=0,qd=query))
			i = i + 1
		
if __name__ == "__main__":
	usage()
	if options.SrvDns and options.Number and options.Domain:
		mysniff=sniffer(options.SrvDns,options.Number,options.SrcHost)
		print "Open file tmp.dat"
		print "mysniff.start"
		mysniff.start()
		myclient=sender(options.SrvDns,options.Domain,options.Number)
		myclient.start()

        

