from protocol_enumerators import ethernetip_enum as eip
from protocol_enumerators import s7_enum as s7
from protocol_enumerators import bacnet as bac
from protocol_enumerators import modbus
from helpers.port_service_helper import psdata
from protocol_enumerators import omron
import binascii
import os
from helpers.Packet_Analyzer import Packet_Analyzer
import sys

def analyse_protocol(protocols,pkt):
	try:
		dev_type = "Unknown"
		vendor = "Unknown"
		firmware = "Unknown"
		model = "Unknown"
		inhex = binascii.hexlify(bytes(pkt))
		pa = Packet_Analyzer()
		if ("enip" in protocols):
			print(protocols)
			res = eip.get_info(pa.get_ip(inhex),
							   int(pa.get_tcp_port(inhex)) if "tcp" in protocols else int(pa.get_udp_port(inhex)))
			if (res):
				dev_type = res['Type']
				vendor = res['Vendor']
				firmware = res['ProductName']
				model = res['SerialNumber']
		elif ("s7comm" in protocols):
			res = s7.get_info(eip.get_info(pa.get_ip(inhex), int(pa.get_tcp_port(inhex)) if "tcp" in protocols else int(
				pa.get_udp_port(inhex))))
			if (res):
				dev_type = res['Module Type'] + " " + res['System Name']
				vendor = res['Copyright']
				firmware = res['Module'] + " " + res['Version']
				model = res['Serial Number']
		elif ("bacnet" in protocols):
			res = bac.get_info(eip.get_info(pa.get_ip(inhex), int(pa.get_tcp_port(inhex)) if "tcp" in protocols else int(
				pa.get_udp_port(inhex))))
			if (res):
				dev_type = res['desc']
				vendor = res['vendorid']
				firmware = res['firmware']
				model = res['model']
		elif ("modbus" in protocols):
			res = modbus.get_info(eip.get_info(pa.get_ip(inhex), int(pa.get_tcp_port(inhex)) if "tcp" in protocols else int(
				pa.get_udp_port(inhex))), False)
			print(inhex)
			if (res):
				dev_type = res['Device identification']
				vendor = res['Slave ID data']
				model = res['sid']
		elif ("omron" in protocols):
			res = omron.get_info(eip.get_info(pa.get_ip(inhex), int(pa.get_tcp_port(inhex)) if "tcp" in protocols else int(
				pa.get_udp_port(inhex))), False)
			if (res):
				dev_type = 'Omron Device'
				vendor = 'Omron Devices'
				firmware = res['Controller Version']
				model = res['Controller Model']
		else:
			port_no = str(pa.get_tcp_port(inhex)) if "tcp" in protocols else str(
				pa.get_udp_port(inhex)) if "udp" in protocols else "Unknown"
			dev_type = psdata[port_no] if port_no in psdata else "Unknown"
			vendor = pa.get_vendor(pa.get_mac(inhex))
		return dev_type, vendor, firmware, model
	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]
		print(exc_type, fname, exc_tb.tb_lineno, e)



def update_protocol(protocols,pkt):
	try:
		dev_type="Unknown"
		vendor="Unknown"
		firmware="Unknown"
		model="Unknown"
		inhex = binascii.hexlify(bytes(pkt))
		pa=Packet_Analyzer()
		if("enip" in protocols):
			res=eip.get_info(pa.get_ip(inhex) ,int(pa.get_tcp_port(inhex)) if "tcp" in protocols else int(pa.get_udp_port(inhex)))
			if(res):
				dev_type=res['Type']
				vendor=res['Vendor']
				firmware=res['ProductName']
				model=res['SerialNumber']
		elif("s7comm" in protocols):
			res=s7.get_info(pa.get_ip(inhex) ,int(pa.get_tcp_port(inhex)) if "tcp" in protocols else int(pa.get_udp_port(inhex)))
			if(res):
				dev_type=res['Module Type']+" "+res['System Name']
				vendor=res['Copyright']
				firmware=res['Module']+" "+res['Version']
				model=res['Serial Number']
		elif("bacnet" in protocols):
			res=bac.get_info(pa.get_ip(inhex) ,int(pa.get_tcp_port(inhex)) if "tcp" in protocols else int(pa.get_udp_port(inhex)))
			if(res):
				dev_type=res['desc']
				vendor=res['vendorid']
				firmware=res['firmware']
				model=res['model']
		elif("modbus" in protocols):
			res=modbus.get_info(pa.get_ip(inhex) ,int(pa.get_tcp_port(inhex)) if "tcp" in protocols else int(pa.get_udp_port(inhex)),False)
			if(res):
				dev_type=res['Device identification']
				vendor=res['Slave ID data']
				model=res['sid']
		elif("omron" in protocols):
			res=omron.get_info(pa.get_ip(inhex) ,int(pa.get_tcp_port(inhex)) if "tcp" in protocols else int(pa.get_udp_port(inhex)),False)
			if(res):
				dev_type='Omron Device'
				vendor='Omron Devices'
				firmware=res['Controller Version']
				model=res['Controller Model']
		return dev_type,vendor,firmware,model
	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]
		print(exc_type, fname, exc_tb.tb_lineno, e)