<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def __lookup(self, ltype, **kwargs):
 		"""Generic Lookup function 		@type ltype: str 		@type rvalues: list 		@type ip: str 		@type mac: str 		@type name: str 		@rtype: dict or str (if len(rvalues) == 1) or None 		@raises ValueError: 		@raises OmapiError: 		@raises OmapiErrorNotFound: if no host object with the given name 				could be found or the object lacks an ip address or mac 		@raises socket.error: 		"""

		ltype_utf = ltype.encode("utf-8")
		assert ltype_utf in [b"host", b"lease"]
		msg = OmapiMessage.open(ltype_utf)
		for k in kwargs:
			if k == "raw":
				continue
			_k = k.replace("_", "-")
			if _k in ["ip", "ip-address"]:
				msg.obj.append((b"ip-address", pack_ip(kwargs[k])))
			elif _k in ["mac", "hardware-address"]:
				msg.obj.append((b"hardware-address", pack_mac(kwargs[k])))
				msg.obj.append((b"hardware-type", struct.pack("!I", 1)))
			elif _k == "name":
				msg.obj.append((b"name", kwargs[k].encode('utf-8')))
			else:
				msg.obj.append((str(k).encode(), kwargs[k].encode('utf-8')))
		response = self.query_server(msg)
		if response.opcode != OMAPI_OP_UPDATE:
			raise OmapiErrorNotFound()
		if "raw" in kwargs and kwargs["raw"]:
			return dict(response.obj)
		res = dict()
		for k, v in dict(response.obj).items():
			_k = k.decode('utf-8')
			try:
				if _k == "ip-address":
					v = unpack_ip(v)
				elif _k in ["hardware-address"]:
					v = unpack_mac(v)
				elif _k in ["starts", "ends", "tstp", "tsfp", "atsfp", "cltt", "subnet", "pool", "state", "hardware-type"]:
					v = struct.unpack(">I", v)[0]
				elif _k in ["flags"]:
					v = struct.unpack(">I", v)[0]
			except struct.error:
				pass
			res[_k] = v
		return res