// File: davidgfnet[P]tadns/tadns_common.cc
// Function: serialize_udp_packet(dns_packet*, unsigned char*)
unsigned serialize_udp_packet(struct dns_packet *in, uint8_t *out) {
    uint8_t *oout = out;
    const uint8_t *e = out + DNS_PACKET_LEN;
    struct header *h = (struct header*)out;

    h->tid      = htons(in->header.tid);
    h->flags    = htons(in->header.flags);
    h->nqueries = htons(in->header.nqueries);
    h->nanswers = htons(in->header.nanswers);
    h->nauth    = htons(in->header.nauth);
    h->nother   = htons(in->header.nother);

    out = &h->data[0];

    for (const auto &q: in->questions) {
        unsigned s = serializeName(q.name, out);
        out += s;

        if (out + 4 >= e) return 0;

        ((uint16_t*)out)[0] = htons(q.qtype);
        ((uint16_t*)out)[1] = htons(q.qclass);
        out += 4;
    }

    for (unsigned i = 0; i < RESPONSE_LAST; i++) {
        for (const auto &r: in->answers) {
            if (r.resptype == i) {
                out += serialize_answer(&r, out);
            }
        }
    }

    return out - oout;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rax
addq $0x800, %rax            # imm = 0x800
movq %rax, -0x28(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movzwl (%rax), %edi
callq 0x3070
movw %ax, %cx
movq -0x30(%rbp), %rax
movw %cx, (%rax)
movq -0x10(%rbp), %rax
movzwl 0x2(%rax), %edi
callq 0x3070
movw %ax, %cx
movq -0x30(%rbp), %rax
movw %cx, 0x2(%rax)
movq -0x10(%rbp), %rax
movzwl 0x4(%rax), %edi
callq 0x3070
movw %ax, %cx
movq -0x30(%rbp), %rax
movw %cx, 0x4(%rax)
movq -0x10(%rbp), %rax
movzwl 0x6(%rax), %edi
callq 0x3070
movw %ax, %cx
movq -0x30(%rbp), %rax
movw %cx, 0x6(%rax)
movq -0x10(%rbp), %rax
movzwl 0x8(%rax), %edi
callq 0x3070
movw %ax, %cx
movq -0x30(%rbp), %rax
movw %cx, 0x8(%rax)
movq -0x10(%rbp), %rax
movzwl 0xa(%rax), %edi
callq 0x3070
movw %ax, %cx
movq -0x30(%rbp), %rax
movw %cx, 0xa(%rax)
movq -0x30(%rbp), %rax
addq $0xc, %rax
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rdi
callq 0x5930
movq %rax, -0x40(%rbp)
movq -0x38(%rbp), %rdi
callq 0x5760
movq %rax, -0x48(%rbp)
leaq -0x40(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x181f0
testb $0x1, %al
jne 0x17ef7
jmp 0x17fd5
leaq -0x40(%rbp), %rdi
callq 0x18230
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rsi
addq $0x8, %rsi
leaq -0x78(%rbp), %rdi
movq %rdi, -0xb8(%rbp)
callq 0x3160
movq -0xb8(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x17a50
movl %eax, -0xac(%rbp)
jmp 0x17f34
leaq -0x78(%rbp), %rdi
callq 0x3200
movl -0xac(%rbp), %eax
movl %eax, -0x54(%rbp)
movl -0x54(%rbp), %ecx
movq -0x18(%rbp), %rax
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
addq $0x4, %rax
cmpq -0x28(%rbp), %rax
jb 0x17f8d
movl $0x0, -0x4(%rbp)
jmp 0x180b2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x3200
jmp 0x180be
movq -0x50(%rbp), %rax
movzwl (%rax), %edi
callq 0x3070
movw %ax, %cx
movq -0x18(%rbp), %rax
movw %cx, (%rax)
movq -0x50(%rbp), %rax
movzwl 0x2(%rax), %edi
callq 0x3070
movw %ax, %cx
movq -0x18(%rbp), %rax
movw %cx, 0x2(%rax)
movq -0x18(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x18(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x18250
jmp 0x17ee1
movl $0x0, -0x88(%rbp)
cmpl $0x3, -0x88(%rbp)
jae 0x180a4
movq -0x10(%rbp), %rax
addq $0x28, %rax
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rdi
callq 0x3cf0
movq %rax, -0x98(%rbp)
movq -0x90(%rbp), %rdi
callq 0x3d20
movq %rax, -0xa0(%rbp)
leaq -0x98(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x3d50
testb $0x1, %al
jne 0x1803a
jmp 0x1808e
leaq -0x98(%rbp), %rdi
callq 0x3d90
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rax
movl 0x4(%rax), %eax
cmpl -0x88(%rbp), %eax
jne 0x1807e
movq -0xa8(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x17b80
movl %eax, %ecx
movq -0x18(%rbp), %rax
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, -0x18(%rbp)
jmp 0x18080
leaq -0x98(%rbp), %rdi
callq 0x3db0
jmp 0x18021
jmp 0x18090
movl -0x88(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x88(%rbp)
jmp 0x17fdf
movq -0x18(%rbp), %rax
movq -0x20(%rbp), %rcx
subq %rcx, %rax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xc0, %rsp
popq %rbp
retq
movq -0x80(%rbp), %rdi
callq 0x3530
nopw (%rax,%rax)