// File: hugosantos[P]dbeacon/protocol.cpp
// Function: build_report(unsigned char*, int, int, bool)
int build_report(uint8_t *buff, int maxlen, int type, bool publishsources) {
	if (maxlen < 4)
		return -1;

	// 0-2 magic
	*((uint16_t *)buff) = htons(0xbeac);

	// 3 version
	buff[2] = PROTO_VER;

	// 4 packet type
	buff[3] = 1; // Report

	buff[4] = defaultTTL; // Original Hop Limit

	int ptr = 5;

	if (!write_tlv_string(buff, maxlen, ptr, T_BEAC_NAME, beaconName.c_str()))
		return -1;
	if (!write_tlv_string(buff, maxlen, ptr, T_ADMIN_CONTACT, adminContact.c_str()))
		return -1;

	if (type == WEBSITE_REPORT) {
		for (WebSites::const_iterator j = webSites.begin(); j != webSites.end(); j++)
			if (!write_tlv_string(buff, maxlen, ptr, j->first, j->second.c_str()))
				return -1;
		if (!twoLetterCC.empty()) {
			if (!write_tlv_string(buff, maxlen, ptr, T_CC, twoLetterCC.c_str()))
				return -1;
		}
		if (!write_tlv_uint(buff, maxlen, ptr, T_SOURCE_FLAGS, flags))
			return -1;
		return ptr;
	} else if (type == LEAVE_REPORT) {
		if (!write_tlv_start(buff, maxlen, ptr, T_LEAVE, 0))
			return -1;
		return ptr;
	}

	if (publishsources) {
		uint64_t now = get_timestamp();

		for (Sources::const_iterator i = sources.begin(); i != sources.end(); i++) {
			if (type == MAP_REPORT && !i->second.identified)
				continue;

			if (!i->second.ASM.s.valid && !i->second.SSM.s.valid)
				continue;

			int len = 18;

			if (i->first.family() == AF_INET)
				len = 6;

			if (type == MAP_REPORT) {
				int namelen = i->second.name.size();
				int contactlen = i->second.adminContact.size();
				len += 2 + namelen + 2 + contactlen;
			} else {
				len += (i->second.ASM.s.valid ? 22 : 0) + (i->second.SSM.s.valid ? 22 : 0);
			}

			if (!write_tlv_start(buff, maxlen, ptr, i->first.family() == AF_INET6 ? T_SOURCE_INFO : T_SOURCE_INFO_IPv4, len))
				break;

			if (i->first.family() == AF_INET6) {
				const sockaddr_in6 *addr = i->first.v6();

				memcpy(buff + ptr, &addr->sin6_addr, sizeof(in6_addr));
				memcpy(buff + ptr + 16, &addr->sin6_port, sizeof(uint16_t));

				ptr += 18;
			} else {
				const sockaddr_in *addr = i->first.v4();

				memcpy(buff + ptr, &addr->sin_addr, sizeof(in_addr));
				memcpy(buff + ptr + 4, &addr->sin_port, sizeof(uint16_t));

				ptr += 6;
			}

			if (type == MAP_REPORT) {
				write_tlv_string(buff, maxlen, ptr, T_BEAC_NAME, i->second.name.c_str());
				write_tlv_string(buff, maxlen, ptr, T_ADMIN_CONTACT, i->second.adminContact.c_str());
			} else {
				uint32_t age = (now - i->second.creation) / 1000;

				if (i->second.ASM.s.valid)
					write_tlv_stats(buff, maxlen, ptr, T_ASM_STATS, age, i->second.sttl, i->second.ASM);
				if (i->second.SSM.s.valid)
					write_tlv_stats(buff, maxlen, ptr, T_SSM_STATS, age, i->second.sttl, i->second.SSM);
			}
		}
	}

	return ptr;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x150, %rsp            # imm = 0x150
movb %cl, %al
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
andb $0x1, %al
movb %al, -0x19(%rbp)
cmpl $0x4, -0x14(%rbp)
jge 0x1875e
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x18e9b
movl $0xbeac, %edi           # imm = 0xBEAC
callq 0x4050
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, (%rax)
movq -0x10(%rbp), %rax
movb $0x1, 0x2(%rax)
movq -0x10(%rbp), %rax
movb $0x1, 0x3(%rax)
leaq 0x2acf(%rip), %rax      # 0x1b258
movl (%rax), %eax
movb %al, %cl
movq -0x10(%rbp), %rax
movb %cl, 0x4(%rax)
movl $0x5, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xb0(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0xa4(%rbp)
leaq 0x10cf2(%rip), %rdi     # 0x294a8
callq 0x41b0
movq -0xb0(%rbp), %rdi
movl -0xa4(%rbp), %esi
movq %rax, %r8
leaq -0x20(%rbp), %rdx
movl $0x6e, %ecx
callq 0x18eb0
testb $0x1, %al
jne 0x187e9
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x18e9b
movq -0x10(%rbp), %rax
movq %rax, -0xc0(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0xb4(%rbp)
leaq 0x10cc4(%rip), %rdi     # 0x294c8
callq 0x41b0
movq -0xc0(%rbp), %rdi
movl -0xb4(%rbp), %esi
movq %rax, %r8
leaq -0x20(%rbp), %rdx
movl $0x61, %ecx
callq 0x18eb0
testb $0x1, %al
jne 0x18837
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x18e9b
cmpl $0x55, -0x18(%rbp)
jne 0x189ad
leaq 0x10cf0(%rip), %rdi     # 0x29538
callq 0xf830
movq %rax, -0x30(%rbp)
leaq -0x28(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0xe150
leaq 0x10cd3(%rip), %rdi     # 0x29538
callq 0xdf80
movq %rax, -0x40(%rbp)
leaq -0x38(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0xe150
leaq -0x28(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0xf860
testb $0x1, %al
jne 0x18891
jmp 0x18913
movq -0x10(%rbp), %rax
movq %rax, -0xd0(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0xc8(%rbp)
leaq -0x28(%rbp), %rdi
callq 0xf890
movl (%rax), %eax
movb %al, -0xc1(%rbp)
leaq -0x28(%rbp), %rdi
callq 0xf890
movq %rax, %rdi
addq $0x8, %rdi
callq 0x41b0
movq -0xd0(%rbp), %rdi
movl -0xc8(%rbp), %esi
movq %rax, %r8
movb -0xc1(%rbp), %al
leaq -0x20(%rbp), %rdx
movzbl %al, %ecx
callq 0x18eb0
testb $0x1, %al
jne 0x188fd
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x18e9b
jmp 0x188ff
leaq -0x28(%rbp), %rdi
xorl %esi, %esi
callq 0xf8b0
movq %rax, -0x48(%rbp)
jmp 0x1885e
leaq 0x10bce(%rip), %rdi     # 0x294e8
callq 0x46e0
testb $0x1, %al
jne 0x18973
movq -0x10(%rbp), %rax
movq %rax, -0xe0(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0xd4(%rbp)
leaq 0x10baa(%rip), %rdi     # 0x294e8
callq 0x41b0
movq -0xe0(%rbp), %rdi
movl -0xd4(%rbp), %esi
movq %rax, %r8
leaq -0x20(%rbp), %rdx
movl $0x43, %ecx
callq 0x18eb0
testb $0x1, %al
jne 0x18971
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x18e9b
jmp 0x18973
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
leaq 0x10c6b(%rip), %rax     # 0x295ec
movl (%rax), %r8d
leaq -0x20(%rbp), %rdx
movl $0x46, %ecx
callq 0x18f60
testb $0x1, %al
jne 0x189a2
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x18e9b
movl -0x20(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x18e9b
cmpl $0x56, -0x18(%rbp)
jne 0x189e6
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
leaq -0x20(%rbp), %rdx
movl $0x51, %ecx
xorl %r8d, %r8d
callq 0x18fe0
testb $0x1, %al
jne 0x189db
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x18e9b
movl -0x20(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x18e9b
jmp 0x189e8
testb $0x1, -0x19(%rbp)
je 0x18e95
callq 0x184e0
movq %rax, -0x50(%rbp)
leaq 0x10b06(%rip), %rdi     # 0x29508
callq 0xf550
movq %rax, -0x60(%rbp)
leaq -0x58(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0xf8f0
leaq 0x10ae9(%rip), %rdi     # 0x29508
callq 0xb270
movq %rax, -0x70(%rbp)
leaq -0x68(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0xf8f0
leaq -0x58(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0xf910
testb $0x1, %al
jne 0x18a4b
jmp 0x18e93
cmpl $0x54, -0x18(%rbp)
jne 0x18a68
leaq -0x58(%rbp), %rdi
callq 0xf940
testb $0x1, 0x3d8(%rax)
jne 0x18a68
jmp 0x18e7c
leaq -0x58(%rbp), %rdi
callq 0xf940
testb $0x1, 0x16c(%rax)
jne 0x18a91
leaq -0x58(%rbp), %rdi
callq 0xf940
testb $0x1, 0x264(%rax)
jne 0x18a91
jmp 0x18e7c
movl $0x12, -0x74(%rbp)
leaq -0x58(%rbp), %rdi
callq 0xf940
movq %rax, %rdi
callq 0x170e0
cmpl $0x2, %eax
jne 0x18ab5
movl $0x6, -0x74(%rbp)
cmpl $0x54, -0x18(%rbp)
jne 0x18b13
leaq -0x58(%rbp), %rdi
callq 0xf940
movq %rax, %rdi
addq $0x80, %rdi
addq $0x290, %rdi            # imm = 0x290
callq 0x42e0
movl %eax, -0x78(%rbp)
leaq -0x58(%rbp), %rdi
callq 0xf940
movq %rax, %rdi
addq $0x80, %rdi
addq $0x2b0, %rdi            # imm = 0x2B0
callq 0x42e0
movl %eax, -0x7c(%rbp)
movl -0x78(%rbp), %eax
addl $0x2, %eax
addl $0x2, %eax
addl -0x7c(%rbp), %eax
addl -0x74(%rbp), %eax
movl %eax, -0x74(%rbp)
jmp 0x18b64
leaq -0x58(%rbp), %rdi
callq 0xf940
movb 0x16c(%rax), %dl
xorl %eax, %eax
movl $0x16, %ecx
testb $0x1, %dl
cmovnel %ecx, %eax
movl %eax, -0xe4(%rbp)
leaq -0x58(%rbp), %rdi
callq 0xf940
movq %rax, %rcx
movl -0xe4(%rbp), %eax
movb 0x264(%rcx), %sil
xorl %ecx, %ecx
movl $0x16, %edx
testb $0x1, %sil
cmovnel %edx, %ecx
addl %ecx, %eax
addl -0x74(%rbp), %eax
movl %eax, -0x74(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xf0(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0xe8(%rbp)
leaq -0x58(%rbp), %rdi
callq 0xf940
movq %rax, %rdi
callq 0x170e0
movq -0xf0(%rbp), %rdi
movl -0xe8(%rbp), %esi
movl %eax, %edx
movl $0x69, %eax
movl $0x49, %ecx
cmpl $0xa, %edx
cmovel %ecx, %eax
movl -0x74(%rbp), %r8d
leaq -0x20(%rbp), %rdx
movzbl %al, %ecx
callq 0x18fe0
testb $0x1, %al
jne 0x18bc1
jmp 0x18e93
leaq -0x58(%rbp), %rdi
callq 0xf940
movq %rax, %rdi
callq 0x170e0
cmpl $0xa, %eax
jne 0x18c32
leaq -0x58(%rbp), %rdi
callq 0xf940
movq %rax, %rdi
callq 0x17100
movq %rax, -0x88(%rbp)
movq -0x10(%rbp), %rax
movslq -0x20(%rbp), %rcx
movq -0x88(%rbp), %rdx
movq 0x8(%rdx), %rsi
movq %rsi, (%rax,%rcx)
movq 0x10(%rdx), %rdx
movq %rdx, 0x8(%rax,%rcx)
movq -0x10(%rbp), %rax
movslq -0x20(%rbp), %rcx
movq -0x88(%rbp), %rdx
movw 0x2(%rdx), %dx
movw %dx, 0x10(%rax,%rcx)
movl -0x20(%rbp), %eax
addl $0x12, %eax
movl %eax, -0x20(%rbp)
jmp 0x18c80
leaq -0x58(%rbp), %rdi
callq 0xf940
movq %rax, %rdi
callq 0x17110
movq %rax, -0x90(%rbp)
movq -0x10(%rbp), %rax
movslq -0x20(%rbp), %rcx
movq -0x90(%rbp), %rdx
movl 0x4(%rdx), %edx
movl %edx, (%rax,%rcx)
movq -0x10(%rbp), %rax
movslq -0x20(%rbp), %rcx
movq -0x90(%rbp), %rdx
movw 0x2(%rdx), %dx
movw %dx, 0x4(%rax,%rcx)
movl -0x20(%rbp), %eax
addl $0x6, %eax
movl %eax, -0x20(%rbp)
cmpl $0x54, -0x18(%rbp)
jne 0x18d31
movq -0x10(%rbp), %rax
movq %rax, -0x110(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0x104(%rbp)
leaq -0x58(%rbp), %rdi
callq 0xf940
movq %rax, %rdi
addq $0x80, %rdi
addq $0x290, %rdi            # imm = 0x290
callq 0x41b0
movq -0x110(%rbp), %rdi
movl -0x104(%rbp), %esi
movq %rax, %r8
leaq -0x20(%rbp), %rdx
movl $0x6e, %ecx
callq 0x18eb0
movq -0x10(%rbp), %rax
movq %rax, -0x100(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0xf4(%rbp)
leaq -0x58(%rbp), %rdi
callq 0xf940
movq %rax, %rdi
addq $0x80, %rdi
addq $0x2b0, %rdi            # imm = 0x2B0
callq 0x41b0
movq -0x100(%rbp), %rdi
movl -0xf4(%rbp), %esi
movq %rax, %r8
leaq -0x20(%rbp), %rdx
movl $0x61, %ecx
callq 0x18eb0
jmp 0x18e7a
movq -0x50(%rbp), %rax
movq %rax, -0x118(%rbp)
leaq -0x58(%rbp), %rdi
callq 0xf940
movq %rax, %rcx
movq -0x118(%rbp), %rax
subq 0x100(%rcx), %rax
movl $0x3e8, %ecx            # imm = 0x3E8
xorl %edx, %edx
divq %rcx
movl %eax, -0x94(%rbp)
leaq -0x58(%rbp), %rdi
callq 0xf940
testb $0x1, 0x16c(%rax)
je 0x18def
movq -0x10(%rbp), %rax
movq %rax, -0x130(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0x124(%rbp)
movl -0x94(%rbp), %eax
movl %eax, -0x120(%rbp)
leaq -0x58(%rbp), %rdi
callq 0xf940
movl 0x108(%rax), %eax
movl %eax, -0x11c(%rbp)
leaq -0x58(%rbp), %rdi
callq 0xf940
movq -0x130(%rbp), %rdi
movl -0x124(%rbp), %esi
movl -0x120(%rbp), %r8d
movl -0x11c(%rbp), %r9d
addq $0x80, %rax
addq $0xa0, %rax
leaq -0x20(%rbp), %rdx
movl $0x41, %ecx
movq %rax, (%rsp)
callq 0x19060
leaq -0x58(%rbp), %rdi
callq 0xf940
testb $0x1, 0x264(%rax)
je 0x18e78
movq -0x10(%rbp), %rax
movq %rax, -0x148(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0x13c(%rbp)
movl -0x94(%rbp), %eax
movl %eax, -0x138(%rbp)
leaq -0x58(%rbp), %rdi
callq 0xf940
movl 0x108(%rax), %eax
movl %eax, -0x134(%rbp)
leaq -0x58(%rbp), %rdi
callq 0xf940
movq -0x148(%rbp), %rdi
movl -0x13c(%rbp), %esi
movl -0x138(%rbp), %r8d
movl -0x134(%rbp), %r9d
addq $0x80, %rax
addq $0x198, %rax            # imm = 0x198
leaq -0x20(%rbp), %rdx
movl $0x53, %ecx
movq %rax, (%rsp)
callq 0x19060
jmp 0x18e7a
jmp 0x18e7c
leaq -0x58(%rbp), %rdi
xorl %esi, %esi
callq 0xf970
movq %rax, -0xa0(%rbp)
jmp 0x18a18
jmp 0x18e95
movl -0x20(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x150, %rsp            # imm = 0x150
popq %rbp
retq
nopw (%rax,%rax)