"""
 There is an information gathering for every succesful cyber attack
 Which in this case is TCP port scanner

""" 
# TCP port 80 for web server
# TCP port 25 for email server
# TCP port 21 for file transfer server 

# Calling 3rd-party libraries
from threading import * 
import optparse
from socket import *

screenLock = Semaphore(value = 1)

# Function for connection scan
def connectionScan(targetHost, targetPort):
	try:
		# Creates an object from socket class
		connectionSocket = socket(AF_INET, SOCK_STREAM)
		# then connect to targetHost with using targetPort
		connectionSocket.connect((targetHost, targetPort))
		# Sends a junk string message to the "open" port and wait for the response
		connectionSocket.send('hello world\r\n')
		# Get the results and collect them into variable
		result = connectionSocket.recv(100)
		# Must to call screenlock to avoid complicated messages instantly
		screenLock.acquire()
		# Prints the message to screen that targetPort is being locked on
		print('[+]%d/tcp open' % targetPort)
		# Print the info about the host
		print('[+] ' + str(result))
	# If something goes wrong throws and error:
	except: 
		screenLock.acquire() 
		print('[-]%d/tcp closed' % targetPort)
	
	screenLock.release()
	# then close the opened connection
	connectionSocket.close()

# Takes targetHost and targetPorts as arguments
def portScan(targetHost, targetPorts):
	try:
		# Locks the ip
		targetIP = gethostbyname(targetHost)
	except:
		# If cannot find the ip 
		print("[-] Cannot resolve '%s' : Unknown host" % targetHost)
		# Finishes the function with returning to nothing
		return 
	try:
		targetName = gethostbyaddr(targetIP)
		print("\n[+] Scan results for: " + targetName[0])

	except: print("\n[+] Scan Results for: " + targetIP)
	# Delays 1s at a time 
	setdefaulttimeout(1)

	# Scans every port one by one within th given arguments
	for targetPort in targetPorts:
		t = Thread(target = connectionScan, args = (targetHost, int(targetPort)))
		t.start()

def main():
	# Creates an object from optparse class
	parser = optparse.OptionParser("usage%prog " + "-H <target Host> -p <target port>")
	# Specifiying the usage from terminal
	parser.add_option('-H', dest = 'targetHost', type = 'string', help = 'specify target host')
	parser.add_option('-p', dest = 'targetPort', type = 'string', help = 'specify target port[s] separated by comma')
	(options, args) = parser.parse_args()

	# Get the input and converts to our format
	targetHost = options.targetHost
	targetPorts = str(options.targetPort).split(', ')
	# If user entered nothing warn them and quit
	if (targetHost == None) | (targetPorts[0] == None):
		print('[-] Specify target host and port[s]')
		exit(0)
	# Runs the portScan function
	portScan(targetHost, targetPorts)

if __name__ == '__main__':
	main()


""" Example usage
In terminal 
python nameofthefile.py -H <host ip> -p <host port>
"""