// File: madpilot[P]mDNSResolver/src/Answer.cpp
// Function: mDNSResolver::Answer::resolve(unsigned char*, unsigned int, unsigned int*, mDNSResolver::Cache&)
MDNS_RESULT Answer::resolve(unsigned char *buffer, unsigned int len, unsigned int* offset, Cache& cache) {
    char* assembled = (char *)malloc(sizeof(char) * MDNS_MAX_NAME_LEN);
    if(assembled == NULL) {
      return E_MDNS_OUT_OF_MEMORY;
    }
    int nameLen = Answer::assembleName(buffer, len, offset, &assembled);

    if(nameLen == -1 * E_MDNS_POINTER_OVERFLOW) {
      free(assembled);
      return -1 * nameLen;
    }

    char *name = (char *)malloc(sizeof(char) * nameLen);
    if(name == NULL) {
      free(assembled);
      return E_MDNS_OUT_OF_MEMORY;
    }
    parseName(&name, assembled, strlen(assembled));
    int cacheIndex = cache.search(name);
    free(name);

    unsigned int type = (buffer[(*offset)++] << 8) + buffer[(*offset)++];
    unsigned int aclass = (buffer[(*offset)++] << 8) + buffer[(*offset)++];
    unsigned long ttl = (buffer[(*offset)++] << 24) + (buffer[(*offset)++] << 16) + (buffer[(*offset)++] << 8) + buffer[(*offset)++];
    unsigned int dataLen = (buffer[(*offset)++] << 8) + buffer[(*offset)++];

    if(type == MDNS_A_RECORD && cacheIndex != -1) {
      resolveAName(buffer, len, offset, cache[cacheIndex], ttl, dataLen);
    } else if(type == MDNS_CNAME_RECORD && cacheIndex != -1) {
      cache[cacheIndex].resolved = false;
      cache[cacheIndex].ttl = ttl;

      unsigned int dataOffset = (*offset);
      (*offset) += dataLen;
      dataLen = Answer::assembleName(buffer, len, &dataOffset, &assembled, dataLen);

      if(dataLen == -1 * E_MDNS_POINTER_OVERFLOW) {
        free(assembled);
        return -1 * dataLen;
      }

      Response r;
      char* responseName = &*r.name;
      parseName(&responseName, assembled, dataLen - 1);
      int cnameIndex = cache.search(r);

      if(cnameIndex == -1) {
        cache.insert(r);
        cnameIndex = cache.search(r);
      }

      cache[cacheIndex].cname = &cache[cnameIndex];
    } else {
      // Not an A record or a CNAME. Ignore.
      (*offset) += dataLen;
    }

    free(assembled);
    return E_MDNS_OK;
  }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x310, %rsp            # imm = 0x310
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movl $0xff, %edi
callq 0xc670
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0x7f0eb
movl $0x27, -0x4(%rbp)
jmp 0x7f521
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
movq -0x20(%rbp), %rdx
leaq -0x30(%rbp), %rcx
callq 0x7f720
movl %eax, -0x34(%rbp)
cmpl $-0x22, -0x34(%rbp)
jne 0x7f120
movq -0x30(%rbp), %rdi
callq 0xc5c0
imull $0xffffffff, -0x34(%rbp), %eax # imm = 0xFFFFFFFF
movl %eax, -0x4(%rbp)
jmp 0x7f521
movslq -0x34(%rbp), %rdi
shlq $0x0, %rdi
callq 0xc670
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
jne 0x7f14d
movq -0x30(%rbp), %rdi
callq 0xc5c0
movl $0x27, -0x4(%rbp)
jmp 0x7f521
movq -0x30(%rbp), %rax
movq %rax, -0x2b0(%rbp)
movq -0x30(%rbp), %rdi
callq 0xc220
movq -0x2b0(%rbp), %rsi
movl %eax, %edx
leaq -0x40(%rbp), %rdi
callq 0x7f760
movq -0x28(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x69710
movl %eax, -0x44(%rbp)
movq -0x40(%rbp), %rdi
callq 0xc5c0
movq -0x10(%rbp), %rax
movq -0x20(%rbp), %rdx
movl (%rdx), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, (%rdx)
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
shll $0x8, %eax
movq -0x10(%rbp), %rcx
movq -0x20(%rbp), %rsi
movl (%rsi), %edx
movl %edx, %edi
addl $0x1, %edi
movl %edi, (%rsi)
movl %edx, %edx
movzbl (%rcx,%rdx), %ecx
addl %ecx, %eax
movl %eax, -0x48(%rbp)
movq -0x10(%rbp), %rax
movq -0x20(%rbp), %rdx
movl (%rdx), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, (%rdx)
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
shll $0x8, %eax
movq -0x10(%rbp), %rcx
movq -0x20(%rbp), %rsi
movl (%rsi), %edx
movl %edx, %edi
addl $0x1, %edi
movl %edi, (%rsi)
movl %edx, %edx
movzbl (%rcx,%rdx), %ecx
addl %ecx, %eax
movl %eax, -0x4c(%rbp)
movq -0x10(%rbp), %rax
movq -0x20(%rbp), %rdx
movl (%rdx), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, (%rdx)
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
shll $0x18, %eax
movq -0x10(%rbp), %rcx
movq -0x20(%rbp), %rsi
movl (%rsi), %edx
movl %edx, %edi
addl $0x1, %edi
movl %edi, (%rsi)
movl %edx, %edx
movzbl (%rcx,%rdx), %ecx
shll $0x10, %ecx
addl %ecx, %eax
movq -0x10(%rbp), %rcx
movq -0x20(%rbp), %rsi
movl (%rsi), %edx
movl %edx, %edi
addl $0x1, %edi
movl %edi, (%rsi)
movl %edx, %edx
movzbl (%rcx,%rdx), %ecx
shll $0x8, %ecx
addl %ecx, %eax
movq -0x10(%rbp), %rcx
movq -0x20(%rbp), %rsi
movl (%rsi), %edx
movl %edx, %edi
addl $0x1, %edi
movl %edi, (%rsi)
movl %edx, %edx
movzbl (%rcx,%rdx), %ecx
addl %ecx, %eax
cltq
movq %rax, -0x58(%rbp)
movq -0x10(%rbp), %rax
movq -0x20(%rbp), %rdx
movl (%rdx), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, (%rdx)
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
shll $0x8, %eax
movq -0x10(%rbp), %rcx
movq -0x20(%rbp), %rsi
movl (%rsi), %edx
movl %edx, %edi
addl $0x1, %edi
movl %edi, (%rsi)
movl %edx, %edx
movzbl (%rcx,%rdx), %ecx
addl %ecx, %eax
movl %eax, -0x5c(%rbp)
cmpl $0x1, -0x48(%rbp)
jne 0x7f2ff
cmpl $-0x1, -0x44(%rbp)
je 0x7f2ff
movq -0x10(%rbp), %rax
movq %rax, -0x2c8(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0x2bc(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x2b8(%rbp)
movq -0x28(%rbp), %rdi
movl -0x44(%rbp), %esi
callq 0x694b0
movq -0x2c8(%rbp), %rdi
movl -0x2bc(%rbp), %esi
movq -0x2b8(%rbp), %rdx
movq %rax, %rcx
movq -0x58(%rbp), %r8
movl -0x5c(%rbp), %r9d
callq 0x7f620
jmp 0x7f511
cmpl $0x5, -0x48(%rbp)
jne 0x7f504
cmpl $-0x1, -0x44(%rbp)
je 0x7f504
movq -0x28(%rbp), %rdi
movl -0x44(%rbp), %esi
callq 0x694b0
movb $0x0, 0x108(%rax)
movq -0x58(%rbp), %rax
movq %rax, -0x2d0(%rbp)
movq -0x28(%rbp), %rdi
movl -0x44(%rbp), %esi
callq 0x694b0
movq -0x2d0(%rbp), %rcx
movq %rcx, 0x100(%rax)
movq -0x20(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x60(%rbp)
movl -0x5c(%rbp), %ecx
movq -0x20(%rbp), %rax
addl (%rax), %ecx
movl %ecx, (%rax)
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x5c(%rbp), %r8d
leaq -0x60(%rbp), %rdx
leaq -0x30(%rbp), %rcx
callq 0x7f860
movl %eax, -0x5c(%rbp)
cmpl $-0x22, -0x5c(%rbp)
jne 0x7f398
movq -0x30(%rbp), %rdi
callq 0xc5c0
imull $0xffffffff, -0x5c(%rbp), %eax # imm = 0xFFFFFFFF
movl %eax, -0x4(%rbp)
jmp 0x7f521
leaq -0x178(%rbp), %rdi
movq %rdi, -0x2d8(%rbp)
callq 0x6bca0
movq -0x2d8(%rbp), %rax
movq %rax, -0x180(%rbp)
movq -0x30(%rbp), %rsi
movl -0x5c(%rbp), %edx
decl %edx
leaq -0x180(%rbp), %rdi
callq 0x7f760
jmp 0x7f3d0
movq -0x28(%rbp), %rdi
leaq -0x178(%rbp), %rsi
callq 0x69580
movl %eax, -0x2dc(%rbp)
jmp 0x7f3e8
movl -0x2dc(%rbp), %eax
movl %eax, -0x190(%rbp)
cmpl $-0x1, -0x190(%rbp)
jne 0x7f4a6
movq -0x28(%rbp), %rax
movq %rax, -0x2f0(%rbp)
leaq -0x2a8(%rbp), %rdi
movq %rdi, -0x2e8(%rbp)
leaq -0x178(%rbp), %rsi
movl $0x118, %edx            # imm = 0x118
callq 0xc410
movq -0x2f0(%rbp), %rdi
movq -0x2e8(%rbp), %rsi
callq 0x694d0
jmp 0x7f440
leaq -0x2a8(%rbp), %rdi
callq 0x6bdf0
movq -0x28(%rbp), %rdi
leaq -0x178(%rbp), %rsi
callq 0x69580
movl %eax, -0x2f4(%rbp)
jmp 0x7f464
movl -0x2f4(%rbp), %eax
movl %eax, -0x190(%rbp)
jmp 0x7f4a6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x188(%rbp)
movl %eax, -0x18c(%rbp)
jmp 0x7f4f6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x188(%rbp)
movl %eax, -0x18c(%rbp)
leaq -0x2a8(%rbp), %rdi
callq 0x6bdf0
jmp 0x7f4f6
movq -0x28(%rbp), %rdi
movl -0x190(%rbp), %esi
callq 0x694b0
movq %rax, -0x300(%rbp)
jmp 0x7f4be
movq -0x28(%rbp), %rdi
movl -0x44(%rbp), %esi
callq 0x694b0
movq %rax, -0x308(%rbp)
jmp 0x7f4d3
movq -0x308(%rbp), %rax
movq -0x300(%rbp), %rcx
movq %rcx, 0x110(%rax)
leaq -0x178(%rbp), %rdi
callq 0x6bdf0
jmp 0x7f50f
leaq -0x178(%rbp), %rdi
callq 0x6bdf0
jmp 0x7f52d
movl -0x5c(%rbp), %ecx
movq -0x20(%rbp), %rax
addl (%rax), %ecx
movl %ecx, (%rax)
jmp 0x7f511
movq -0x30(%rbp), %rdi
callq 0xc5c0
movl $0x20, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x310, %rsp            # imm = 0x310
popq %rbp
retq
movq -0x188(%rbp), %rdi
callq 0xc8b0
nopl (%rax)