// File: davidgfnet[P]tadns/tadns_common.cc
// Function: serialize_answer(dns_record const*, unsigned char*)
unsigned serialize_answer(const struct dns_record *rec, uint8_t *out) {
    uint8_t * oout = out;

    bool namec = (rec->rtype == DNS_MX_RECORD || 
                  rec->rtype == DNS_NS_RECORD ||
                  rec->rtype == DNS_CNAME_RECORD);

    // Getting the size is a bit convoluted depending on type and the domain itself
    unsigned dlen = namec ? (rec->addr.size() ? rec->addr.size() + 2 : 1) : rec->addr.size();

    // Name goes first
    out += serializeName(rec->name, out);

    ((uint16_t*)out)[0] = htons(rec->rtype);
    ((uint16_t*)out)[1] = htons(0x0001);  // Assuming Internet yo!
    ((uint32_t*)out)[1] = htonl(rec->ttl);
    ((uint16_t*)out)[4] = htons(dlen);
    out += 10;

    if (namec) {
        out += serializeName(rec->addr, out);
    } else {
        memcpy(out, rec->addr.data(), rec->addr.size());
        out += rec->addr.size();
    }

    return out - oout;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x18(%rbp)
movq -0x8(%rbp), %rcx
movb $0x1, %al
cmpl $0xf, (%rcx)
movb %al, -0x71(%rbp)
je 0x17bc4
movq -0x8(%rbp), %rcx
movb $0x1, %al
cmpl $0x2, (%rcx)
movb %al, -0x71(%rbp)
je 0x17bc4
movq -0x8(%rbp), %rax
cmpl $0x5, (%rax)
sete %al
movb %al, -0x71(%rbp)
movb -0x71(%rbp), %al
andb $0x1, %al
movb %al, -0x19(%rbp)
testb $0x1, -0x19(%rbp)
je 0x17c14
movq -0x8(%rbp), %rdi
addq $0x28, %rdi
callq 0x3240
cmpq $0x0, %rax
je 0x17bfc
movq -0x8(%rbp), %rdi
addq $0x28, %rdi
callq 0x3240
addq $0x2, %rax
movq %rax, -0x80(%rbp)
jmp 0x17c07
movl $0x1, %eax
movq %rax, -0x80(%rbp)
jmp 0x17c07
movq -0x80(%rbp), %rax
movq %rax, -0x88(%rbp)
jmp 0x17c28
movq -0x8(%rbp), %rdi
addq $0x28, %rdi
callq 0x3240
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
movl %eax, -0x20(%rbp)
movq -0x8(%rbp), %rsi
addq $0x8, %rsi
leaq -0x40(%rbp), %rdi
movq %rdi, -0x98(%rbp)
callq 0x3160
movq -0x98(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x17a50
movl %eax, -0x8c(%rbp)
jmp 0x17c62
movl -0x8c(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, -0x10(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x3200
movq -0x8(%rbp), %rax
movl (%rax), %eax
movzwl %ax, %edi
callq 0x3070
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, (%rax)
movl $0x1, %edi
callq 0x3070
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, 0x2(%rax)
movq -0x8(%rbp), %rax
movl 0x48(%rax), %edi
callq 0x3280
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x4(%rax)
movl -0x20(%rbp), %eax
movzwl %ax, %edi
callq 0x3070
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, 0x8(%rax)
movq -0x10(%rbp), %rax
addq $0xa, %rax
movq %rax, -0x10(%rbp)
testb $0x1, -0x19(%rbp)
je 0x17d6e
movq -0x8(%rbp), %rsi
addq $0x28, %rsi
leaq -0x70(%rbp), %rdi
movq %rdi, -0xa8(%rbp)
callq 0x3160
movq -0xa8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x17a50
movl %eax, -0x9c(%rbp)
jmp 0x17d1c
movl -0x9c(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, -0x10(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x3200
jmp 0x17dc5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x3200
jmp 0x17dd9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x3200
jmp 0x17dd9
movq -0x10(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0x8(%rbp), %rdi
addq $0x28, %rdi
callq 0x3460
movq %rax, -0xb0(%rbp)
movq -0x8(%rbp), %rdi
addq $0x28, %rdi
callq 0x3240
movq -0xb8(%rbp), %rdi
movq -0xb0(%rbp), %rsi
movq %rax, %rdx
callq 0x32c0
movq -0x8(%rbp), %rdi
addq $0x28, %rdi
callq 0x3240
addq -0x10(%rbp), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq -0x18(%rbp), %rcx
subq %rcx, %rax
addq $0xc0, %rsp
popq %rbp
retq
movq -0x48(%rbp), %rdi
callq 0x3530
nopw %cs:(%rax,%rax)