import binascii
import json
from protocol_discover_helpers import modbus_discover,enip_discover,s7_discover,omron_discover,bacnet_discover,codesys_discover

class Packet_Analyzer():
	def __init__(self):
		self.data=None
		self.protocol_list={502: modbus_discover,44818:enip_discover,102:s7_discover,9600:omron_discover,47808:bacnet_discover,2455:codesys_discover}

	def identify_protocol(self,hex_pkt):
		protocols=""
		if(hex_pkt[46:48] == b"06"):
			protocols=protocols+"tcp"
			port=self.get_tcp_port(hex_pkt)
			if(port in self.protocol_list):
				port_protocol = self.protocol_list[port].protocol_identify(hex_pkt)
				if (port_protocol):
					protocols = protocols + port_protocol
		if (hex_pkt[46:48] == b"11"):
			protocols = protocols + "udp"
			port = self.get_udp_port(hex_pkt)
			if (port in self.protocol_list):
				port_protocol = self.protocol_list[port].protocol_identify(hex_pkt)
				if(port_protocol):
					protocols = protocols + port_protocol
		return protocols

	def get_ip(self,hex_pkt):
		if(hex_pkt[24:28]==b"0800"):
			ip_inhex= hex_pkt[28+24:28+24+8]
			ip = str(int.from_bytes(binascii.unhexlify(ip_inhex[0:2]), byteorder="little"))+"."+str(int.from_bytes(binascii.unhexlify(ip_inhex[2:4]), byteorder="little"))+"."+str(int.from_bytes(binascii.unhexlify(ip_inhex[4:6]), byteorder="little"))+"."+str(int.from_bytes(binascii.unhexlify(ip_inhex[6:8]), byteorder="little"))
			return ip

	def get_mac(self,hex_pkt):
		souce_mac = hex_pkt[12:24].decode()
		modified_src_mac = ":".join(souce_mac[i:i + 2] for i in range(0, len(souce_mac), 2))
		return modified_src_mac

	def get_tcp_port(self,inhex):
		if(inhex[46:48]==b"06"):
			port = int(inhex[68:72], 16)
			return port

	def get_udp_port(self,inhex):
		if (inhex[46:48] == b"11"):
			port = int(inhex[68:72], 16)
			return port

	def find_mac(self,mac, trim_count=-1):
		try:
			if len(mac[:trim_count]) == 0:
				return "No Mac"
			else:
				res = self.data[mac[:trim_count]]
				return res
		except:
			r = self.find_mac(mac, trim_count - 1)
			return r

	def get_vendor(self,mac):
		f = open("utilities/mac_vendors.json")
		self.data = json.loads(f.read())
		vendor = self.find_mac(mac.upper())
		return vendor

	def get_os(self,inhex):
		try:
			ttl = int(inhex[44:46].decode())
		except:
			ttl = 255
		if ttl <=64:
			return "Unix/Linux Based"
		elif ttl <= 128:
			return "Windows"
		elif ttl <= 254:
			return "Solaris"
		else:
			return "Indeterminate Operating System"