def parse(cls, payload): assert isinstance(payload, bytes) body = ResolutionResponseBody() body.bodyRaw = payload offset = 0 body.handle = utils.uba(payload[offset:]) offset += 4 + len(body.handle) # logger.debug(f"handle : {body.handle}({len(body.handle)})") # logger.debug(f"offset : {offset}/{len(payload)}") if (valueCnt := utils.u32(payload[offset:])) \ > common.MAX_HANDLE_VALUES: raise Exception(f"invalid valueCnt : {valueCnt}")
def calcReferenceSize(payload): assert isinstance(payload, bytes) offset = 0 handleSize = utils.u32(payload[offset:]) offset += 4 + handleSize # handle offset += 4 # index return offset
def parse(cls, payload): assert isinstance(payload, bytes) ref = Reference() offset = 0 ref.handle = utils.uba(payload[offset:]) offset += 4 + len(ref.handle) ref.index = utils.u32(payload[offset:]) offset += 4 return ref
def parse(self, body): assert isinstance(body, bytes) logger.debug(body[:]) offset = 0 self.valueCnt = utils.u32(body[offset:]) offset += 4 for _i in range(self.valueCnt): pass
def parseData(self, data): assert isinstance(data, bytes) offset = 0 refCnt = utils.u32(data[offset:]) offset += 4 refs = [] for _i in range(refCnt): handle = utils.uba(data[offset:]) offset += 4 + len(handle) index = utils.u32(data[offset:]) offset += 4 ref = Reference() ref.setVals(handle, index) refs.append(ref) self.refs = refs assert offset == len(data)
def parseData(self, data): assert isinstance(data, bytes) offset = 0 self.adminPermission = utils.u16(data[offset:]) offset += 2 self.adminID = utils.uba(data[offset:]) offset += 4 + len(self.adminID) self.adminIndex = utils.u32(data[offset:]) offset += 4 assert (offset == len(data) or offset + 2 == len(data)) # todo legacyByteLength
def calcHandleValueSize(payload: bytes, offset: int = 0) -> int: """Calculate the number of bytes required to store the specified value """ assert isinstance(payload, bytes) assert isinstance(offset, int) originalOffset = offset offset += 4 # index offset += 4 # timestamp offset += 1 # ttl type offset += 4 # ttl offset += 1 # permission # type field fieldLen = utils.u32(payload[offset:]) offset += (4 + fieldLen) logger.debug(f"{offset}/{len(payload)} ({offset-originalOffset})") # data field fieldLen = utils.u32(payload[offset:]) offset += (4 + fieldLen) logger.debug(f"{offset}/{len(payload)} ({offset-originalOffset})") # refs refCnt = utils.u32(payload[offset:]) offset += 4 logger.debug(f"{offset}/{len(payload)} ({offset-originalOffset})") logger.debug(f"ref count: {refCnt}") for i in range(refCnt): refLen = utils.u32(payload[offset:]) offset += (4 + refLen + 4 ) # each reference - hdl length + hdl + index logger.debug( f"ref{i} : {offset}/{len(payload)} ({offset-originalOffset})") return offset - originalOffset
def parseData(self, data): assert isinstance(data, bytes) logger.debug("start parsing data for HS_SITE") offset = 0 self.version = utils.u16(data[offset:]) offset += 2 self.majorProtocolVersion = utils.u8(data[offset:]) offset += 1 self.minorProtocolVersion = utils.u8(data[offset:]) offset += 1 self.serialNumber = utils.u16(data[offset:]) offset += 2 self.primaryMask = utils.u8(data[offset:]) offset += 1 self.hashOption = utils.u8(data[offset:]) offset += 1 hashOptionLen = utils.u32(data[offset:]) offset += 4 self.hashOption = data[offset:offset + hashOptionLen] offset += hashOptionLen attributeCnt = utils.u32(data[offset:]) offset += 4 for _i in range(attributeCnt): name = utils.uba(data[offset:]) offset += 4 + len(name) value = utils.uba(data[offset:]) offset += 4 + len(value) self.attributeList.append((name, value)) serverCnt = utils.u32(data[offset:]) offset += 4 servers = [] for _i in range(serverCnt): serverID = utils.u32(data[offset:]) offset += 4 address = data[offset:offset + common.IPV6_SIZE_IN_BYTES] offset += common.IPV6_SIZE_IN_BYTES publicKey = utils.uba(data[offset:]) offset += 4 + len(publicKey) intfCnt = utils.u32(data[offset:]) offset += 4 intfs = [] for _i in range(intfCnt): intfType = utils.u8(data[offset:]) offset += 1 intfProtocol = utils.u8(data[offset:]) offset += 1 intfPort = utils.u32(data[offset:]) offset += 4 intf = ServiceInterface() intf.setVals(intfType, intfProtocol, intfPort) intfs.append(intf) serverRecord = ServerRecord() serverRecord.setVals(serverID, address, publicKey, intfs) servers.append(serverRecord) self.servers = servers logger.debug(f"{offset}/{len(data)}") logger.debug("end parsing data for HS_SITE") assert offset == len(data)
def parse(cls, payload): # refer to `calcHandleValueSize` assert isinstance(payload, bytes) offset = 0 index = utils.u32(payload[offset:]) offset += 4 timestamp = utils.u32(payload[offset:]) offset += 4 ttlType = utils.u8(payload[offset:]) offset += 1 ttl = utils.u32(payload[offset:]) offset += 4 permission = utils.u8(payload[offset:]) offset += 1 valueType = utils.uba(payload[offset:]) offset += 4 + len(valueType) data = utils.uba(payload[offset:]) offset += 4 + len(data) refs = [] refCnt = utils.u32(payload[offset:]) offset += 4 for _i in range(0, refCnt): refLen = Reference.calcReferenceSize(payload[offset:]) ref = Reference.parse(payload[offset:]) offset += refLen refs.append(ref) logger.debug(str(ref)) assert offset == len(payload) valueType = valueType.upper() logger.debug(f"value type : {valueType}") if valueType == b"": raise Exception(f"unimplemented for empty value type") elif valueType == b"URL" or valueType.startswith(b"URL.") \ or valueType == b"EMAIL" or valueType.startswith(b"EMAIL.") \ or valueType == b"HS_ALIAS" or valueType.startswith(b"HS_ALIAS.") \ or valueType == b"HS_SERV" or valueType.startswith(b"HS_SERV.") \ or valueType == b"DESC" or valueType.startswith(b"DESC.") \ or valueType == b"HS_SECKEY" or valueType.startswith(b"HS_SECKEY."): hv = HS_STRING() elif valueType == b"HS_SITE" \ or valueType.startswith(b"HS_SITE.") \ or valueType == b"HS_NA_DELEGATE": hv = HS_SITE() elif valueType == b"HS_ADMIN" or valueType.startswith(b"HS_ADMIN."): hv = HS_ADMIN() elif valueType == b"HS_DSAPUBKEY" or valueType.startswith(b"HS_DSAPUBKEY.") \ or valueType == b"HS_PUBKEY" or valueType.startswith(b"HS_PUBKEY."): hv = HS_PUBKEY() elif valueType == b"HS_VLIST" or valueType.startswith(b"HS_VLIST."): hv = HS_VLIST() elif valueType == b"HS_CERT": hv = HS_CERT() else: logger.warn(f"unsupported value type {valueType}") hv = HandleValue() # hv.index = index # hv.valueType = valueType # hv.data = data # hv.ttlType = ttlType # hv.ttl = ttl # hv.timestamp = timestamp # hv.permission = permission # hv.refs = refs logger.debug( f"before setBasicVals {valueType} : {index} {permission:#x}") hv.setBasicVals(valueType=valueType, index=index, data=data, ttlType=ttlType, ttl=ttl, permission=permission, timestamp=timestamp, refs=refs) hv.parseData(data) return hv