// File: /workspace/github_cpp_makefile_star2_O3/hugosantos[P]dbeacon/protocol.cpp
// Function: handle_nmsg(address const&, unsigned long, int, unsigned char*, int, bool)
void handle_nmsg(const address &from, uint64_t recvdts, int ttl, uint8_t *buff, int len, bool ssm) {
	if (len < 4)
		return;

	if (ntohs(*((uint16_t *)buff)) != 0xbeac)
		return;

	if (buff[2] != PROTO_VER)
		return;

	uint64_t now = get_timestamp();

	if (buff[3] == 0) {
		if (len == 12) {
			uint32_t seq = read_u32(buff + 4);
			uint32_t ts = read_u32(buff + 8);
			getSource(from, 0, now, recvdts, true).update(ttl, seq, ts, now, recvdts, ssm);
		}
		return;
	} else if (buff[3] == 1) {
		if (len < 5)
			return;

		beaconSource &src = getSource(from, 0, now, recvdts, true);

		src.sttl = buff[4];

		len -= 5;

		for (uint8_t *hd = tlv_begin(buff + 5, len); hd; hd = tlv_next(hd, len)) {
			if (verbose > 4) {
				char tmp[64];
				from.to_string(tmp, sizeof(tmp));
				fprintf(stderr, "Parsing TLV (%i, %i) for %s [len is now %i]\n", (int)hd[0], (int)hd[1], tmp, len);
			}

			if (hd[0] == T_BEAC_NAME) {
				string name;
				if (check_string((char *)hd + 2, hd[1], name))
					src.setName(name);
			} else if (hd[0] == T_ADMIN_CONTACT) {
				check_string((char *)hd + 2, hd[1], src.adminContact);
			} else if (hd[0] == T_SOURCE_INFO || hd[0] == T_SOURCE_INFO_IPv4) {
				int blen = hd[0] == T_SOURCE_INFO ? 18 : 6;

				if (hd[1] < blen)
					continue;

				address addr;

				if (hd[0] == T_SOURCE_INFO) {
					sockaddr_in6 *a6 = (sockaddr_in6 *)&addr;

					a6->sin6_family = AF_INET6;

					memcpy(&a6->sin6_addr, hd + 2, sizeof(in6_addr));
					memcpy(&a6->sin6_port, hd + 18, sizeof(uint16_t));
				} else {
					sockaddr_in *a4 = (sockaddr_in *)&addr;

					a4->sin_family = AF_INET;

					memcpy(&a4->sin_addr, hd + 2, sizeof(in_addr));
					memcpy(&a4->sin_port, hd + 6, sizeof(uint16_t));
				}

				beaconExternalStats &stats = src.getExternal(addr, now, recvdts);

				int plen = hd[1] - blen;
				for (uint8_t *pd = tlv_begin(hd + 2 + blen, plen); pd; pd = tlv_next(pd, plen)) {
					if (pd[0] == T_BEAC_NAME) {
						if (check_string((char *)pd + 2, pd[1], stats.name)) {
							stats.identified = !stats.name.empty();
						}
					} else if (pd[0] == T_ADMIN_CONTACT) {
						check_string((char *)pd + 2, pd[1], stats.contact);
					} else if (pd[0] == T_ASM_STATS || pd[0] == T_SSM_STATS) {
						Stats *st = (pd[0] == T_ASM_STATS ? &stats.ASM : &stats.SSM);

						if (!read_tlv_stats(pd, stats, *st))
							break;
						st->lastupdate = now;
					}
				}

				// trigger local SSM join
				if (!addr.is_equal(beaconUnicastAddr)) {
					beaconSource &t = getSource(addr, stats.identified ? stats.name.c_str() : 0, now, recvdts, false);
					if (t.adminContact.empty())
						t.adminContact = stats.contact;
				}
			} else if (hd[0] == T_WEBSITE_GENERIC || hd[0] == T_WEBSITE_LG || hd[0] == T_WEBSITE_MATRIX) {
				string url;
				if (check_string((char *)hd + 2, hd[1], url)) {
					src.webSites[hd[0]] = url;
				}
			} else if (hd[0] == T_CC) {
				if (hd[1] == 2) {
					src.CC = string((char *)hd + 2, 2);
				}
			} else if (hd[0] == T_SOURCE_FLAGS) {
				if (hd[1] == 4)
					src.Flags = read_u32(hd + 2);
			} else if (hd[0] == T_LEAVE) {
				removeSource(from, false);
				break;
			}
		}
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x108, %rsp            # imm = 0x108
cmpl $0x4, %r8d
jl 0xaebe
movq %rcx, %r12
cmpw $0xacbe, (%rcx)         # imm = 0xACBE
jne 0xaebe
cmpb $0x1, 0x2(%r12)
jne 0xaebe
movl %r9d, %r14d
movl %r8d, %ebp
movl %edx, %r13d
movq %rsi, %rbx
movq %rdi, %r15
callq 0xa61c
movq %rax, 0x30(%rsp)
movzbl 0x3(%r12), %eax
cmpl $0x1, %eax
je 0xae7e
testl %eax, %eax
jne 0xaebe
cmpl $0xc, %ebp
jne 0xaebe
movl 0x4(%r12), %ebp
movl 0x8(%r12), %r12d
bswapl %ebp
bswapl %r12d
movq %r15, %rdi
xorl %esi, %esi
movq 0x30(%rsp), %r15
movq %r15, %rdx
movq %rbx, %rcx
movl $0x1, %r8d
callq 0x5c14
movzbl %r14b, %ecx
movl %ecx, (%rsp)
movzbl %r13b, %esi
movq %rax, %rdi
movl %ebp, %edx
movq %r12, %rcx
movq %r15, %r8
movq %rbx, %r9
callq 0x6d20
jmp 0xaebe
cmpl $0x4, %ebp
je 0xaebe
movq %r15, %rdi
xorl %esi, %esi
movq 0x30(%rsp), %rdx
movq %rbx, %rcx
movl $0x1, %r8d
callq 0x5c14
movzbl 0x4(%r12), %ecx
movq %rax, 0x40(%rsp)
movl %ecx, 0x88(%rax)
addl $-0x5, %ebp
cmpl $0x2, %ebp
jb 0xaebe
movzbl 0x6(%r12), %eax
cmpl %eax, %ebp
jae 0xaed0
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
addq $0x5, %r12
movq 0x40(%rsp), %rax
leaq 0x2d0(%rax), %rcx
movq %rcx, 0xf0(%rsp)
leaq 0x328(%rax), %rcx
movq %rcx, 0x100(%rsp)
addq $0x2b0, %rax            # imm = 0x2B0
movq %rax, 0xf8(%rsp)
movq %rbx, 0x50(%rsp)
movq %r15, 0x58(%rsp)
leaq 0x7622(%rip), %rax      # 0x12538
cmpl $0x5, (%rax)
jge 0xb205
movb (%r12), %al
movzbl %al, %ecx
cmpl $0x60, %ecx
jg 0xafc1
addl $-0x43, %ecx
cmpl $0xe, %ecx
ja 0xb28c
leaq 0x27f6(%rip), %rdx      # 0xd738
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
leaq 0x20(%rsp), %rax
movq %rax, 0x10(%rsp)
movq $0x0, 0x18(%rsp)
movb $0x0, 0x20(%rsp)
leaq 0x2(%r12), %rax
movq %rax, 0x8(%rsp)
movzbl 0x1(%r12), %r14d
testq %r14, %r14
je 0xb0a8
movq 0x8(%rsp), %rax
movsbl (%rax), %edi
callq 0x35e0
testl %eax, %eax
je 0xb28c
leaq -0x1(%r14), %r15
xorl %r13d, %r13d
cmpq %r13, %r15
je 0xb0a8
movsbl 0x3(%r12,%r13), %edi
callq 0x35e0
incq %r13
testl %eax, %eax
jne 0xaf98
cmpq %r14, %r13
jae 0xb0ee
jmp 0xb28c
cmpl $0x61, %ecx
je 0xb18e
cmpl $0x69, %ecx
je 0xb04e
cmpl $0x6e, %ecx
jne 0xb28c
leaq 0x20(%rsp), %rax
movq %rax, 0x10(%rsp)
movq $0x0, 0x18(%rsp)
movb $0x0, 0x20(%rsp)
leaq 0x2(%r12), %rax
movq %rax, 0x8(%rsp)
movzbl 0x1(%r12), %r14d
testq %r14, %r14
je 0xb217
movq 0x8(%rsp), %rax
movsbl (%rax), %edi
callq 0x35e0
testl %eax, %eax
je 0xb28c
leaq -0x1(%r14), %r15
xorl %r13d, %r13d
cmpq %r13, %r15
je 0xb217
movsbl 0x3(%r12,%r13), %edi
callq 0x35e0
incq %r13
testl %eax, %eax
jne 0xb025
cmpq %r14, %r13
jae 0xb261
jmp 0xb28c
cmpb $0x49, %al
movl $0x6, %r15d
movl $0x12, %eax
cmovel %eax, %r15d
movzbl 0x1(%r12), %eax
cmpl %eax, %r15d
ja 0xb28c
leaq 0x60(%rsp), %r14
movq %r14, %rdi
callq 0xa23c
leaq 0x2(%r12), %rax
cmpb $0x49, (%r12)
jne 0xb2bf
movw $0xa, 0x60(%rsp)
movups (%rax), %xmm0
leaq 0x70(%rsp), %rax
movups %xmm0, -0x8(%rax)
movl $0x12, %eax
jmp 0xb2d1
leaq 0x70(%rsp), %r15
movq %r15, 0x60(%rsp)
movq 0x8(%rsp), %rsi
addq %rsi, %r14
leaq 0x60(%rsp), %r13
movq %r13, %rdi
movq %r14, %rdx
callq 0x9698
leaq 0x10(%rsp), %rdi
movq %r13, %rsi
callq 0x3460
movq 0x60(%rsp), %rdi
cmpq %r15, %rdi
je 0xb0ee
movq 0x70(%rsp), %rsi
incq %rsi
callq 0x33d0
movzbl (%r12), %eax
movl %eax, 0x60(%rsp)
movq 0x100(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x8096
movq %rax, %rdi
leaq 0x10(%rsp), %rsi
callq 0x31e0
jmp 0xb270
cmpb $0x4, 0x1(%r12)
jne 0xb28c
movl 0x2(%r12), %eax
bswapl %eax
movq 0x40(%rsp), %rcx
movl %eax, 0x2f0(%rcx)
jmp 0xb28c
cmpb $0x2, 0x1(%r12)
jne 0xb28c
leaq 0x70(%rsp), %r14
movq %r14, 0x60(%rsp)
movzwl 0x2(%r12), %eax
movw %ax, 0x70(%rsp)
movq $0x2, 0x68(%rsp)
movb $0x0, 0x72(%rsp)
movq 0xf0(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x3460
movq 0x60(%rsp), %rdi
cmpq %r14, %rdi
jne 0xb1fe
jmp 0xb28c
leaq 0x2(%r12), %r14
movzbl 0x1(%r12), %r13d
testq %r13, %r13
je 0xb1bb
xorl %r15d, %r15d
movsbl (%r14,%r15), %edi
callq 0x35e0
testl %eax, %eax
je 0xb28c
incq %r15
cmpq %r15, %r13
jne 0xb1a1
leaq 0x70(%rsp), %rax
movq %rax, 0x60(%rsp)
addq %r14, %r13
leaq 0x60(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
movq %r13, %rdx
callq 0x9698
movq 0xf8(%rsp), %rdi
movq %r15, %rsi
callq 0x3460
movq 0x60(%rsp), %rdi
leaq 0x70(%rsp), %rax
cmpq %rax, %rdi
je 0xb28c
movq 0x70(%rsp), %rsi
jmp 0xb284
movq %r15, %rdi
movq %r12, %rsi
movl %ebp, %edx
callq 0x37f5
jmp 0xaf1f
leaq 0x70(%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0x8(%rsp), %rsi
addq %rsi, %r14
leaq 0x60(%rsp), %rdi
movq %r14, %rdx
callq 0x9698
leaq 0x10(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x3460
movq 0x60(%rsp), %rdi
leaq 0x70(%rsp), %rax
cmpq %rax, %rdi
je 0xb261
movq 0x70(%rsp), %rsi
incq %rsi
callq 0x33d0
movq 0x40(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x66f4
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
je 0xb28c
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x33d0
movzbl 0x1(%r12), %eax
subl %eax, %ebp
addl $-0x2, %ebp
cmpl $0x2, %ebp
movq 0x58(%rsp), %r15
jl 0xaebe
addq %rax, %r12
addq $0x2, %r12
movzbl 0x1(%r12), %eax
cmpl %eax, %ebp
jae 0xaf0f
jmp 0xaebe
movw $0x2, 0x60(%rsp)
movl (%rax), %eax
movl %eax, 0x64(%rsp)
movl $0x6, %eax
movzwl (%r12,%rax), %eax
movw %ax, 0x62(%rsp)
movq 0x40(%rsp), %rdi
movq %r14, %rsi
movq 0x30(%rsp), %rdx
movq %rbx, %rcx
callq 0x6b5a
movq %rax, 0x38(%rsp)
movzbl 0x1(%r12), %r14d
subl %r15d, %r14d
cmpl $0x2, %r14d
jl 0xb5a1
movl %r15d, %eax
movzbl 0x3(%r12,%rax), %ecx
cmpl %ecx, %r14d
jb 0xb5a1
leaq (%r12,%rax), %r15
addq $0x2, %r15
movq 0x38(%rsp), %rax
leaq 0x88(%rax), %rcx
movq %rcx, 0xe8(%rsp)
addq $0x68, %rax
movq %rax, 0xe0(%rsp)
movb (%r15), %cl
movzbl %cl, %eax
cmpl $0x60, %eax
jg 0xb427
cmpl $0x41, %eax
je 0xb35f
cmpl $0x53, %eax
jne 0xb575
cmpb $0x14, 0x1(%r15)
movq 0x50(%rsp), %rbx
jne 0xb5a1
movq 0x38(%rsp), %rsi
leaq 0x38(%rsi), %rax
leaq 0x10(%rsi), %rdx
cmpb $0x41, %cl
cmoveq %rdx, %rax
movl 0x2(%r15), %ecx
bswapl %ecx
movq %rcx, (%rax)
movl 0x6(%r15), %ecx
bswapl %ecx
movl %ecx, 0x8(%rsi)
movb 0xa(%r15), %cl
movb %cl, 0x25(%rax)
movl 0xb(%r15), %ecx
bswapl %ecx
movl %ecx, 0x10(%rax)
movl 0xf(%r15), %ecx
bswapl %ecx
movl %ecx, 0x14(%rax)
movzbl 0x13(%r15), %ecx
xorps %xmm0, %xmm0
cvtsi2sd %ecx, %xmm0
divsd 0x236e(%rip), %xmm0     # 0xd730
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x18(%rax)
movzbl 0x14(%r15), %ecx
xorps %xmm0, %xmm0
cvtsi2sd %ecx, %xmm0
divsd 0x2349(%rip), %xmm0     # 0xd728
movss 0x233d(%rip), %xmm1     # 0xd724
cmpb $-0x1, %cl
je 0xb3f3
xorps %xmm1, %xmm1
cvtsd2ss %xmm0, %xmm1
movss %xmm1, 0x1c(%rax)
movzbl 0x15(%r15), %ecx
xorps %xmm0, %xmm0
cvtsi2sd %ecx, %xmm0
divsd 0x2324(%rip), %xmm0     # 0xd730
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x20(%rax)
movb $0x1, 0x24(%rax)
movq 0x30(%rsp), %rcx
movq %rcx, 0x8(%rax)
jmp 0xb575
cmpl $0x61, %eax
je 0xb498
cmpl $0x6e, %eax
jne 0xb575
leaq 0x2(%r15), %rax
movq %rax, 0x48(%rsp)
movzbl 0x1(%r15), %ebx
testq %rbx, %rbx
je 0xb51b
movq 0x48(%rsp), %rax
movsbl (%rax), %edi
callq 0x35e0
testl %eax, %eax
je 0xb575
leaq -0x1(%rbx), %rax
movq %rax, 0x8(%rsp)
xorl %r13d, %r13d
cmpq %r13, 0x8(%rsp)
je 0xb51b
movsbl 0x3(%r15,%r13), %edi
callq 0x35e0
incq %r13
testl %eax, %eax
jne 0xb46d
cmpq %rbx, %r13
jae 0xb567
jmp 0xb575
leaq 0x2(%r15), %rax
movq %rax, 0x8(%rsp)
movzbl 0x1(%r15), %r13d
testq %r13, %r13
je 0xb4cb
xorl %ebx, %ebx
movq 0x8(%rsp), %rax
movsbl (%rax,%rbx), %edi
callq 0x35e0
testl %eax, %eax
je 0xb575
incq %rbx
cmpq %rbx, %r13
jne 0xb4ad
leaq 0x20(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x8(%rsp), %rsi
addq %rsi, %r13
leaq 0x10(%rsp), %rbx
movq %rbx, %rdi
movq %r13, %rdx
callq 0x9698
movq 0xe8(%rsp), %rdi
movq %rbx, %rsi
callq 0x3460
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
je 0xb575
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x33d0
jmp 0xb575
leaq 0x20(%rsp), %rax
movq %rbx, %rdx
movq %rax, %rbx
movq %rax, 0x10(%rsp)
movq 0x48(%rsp), %rsi
addq %rsi, %rdx
leaq 0x10(%rsp), %r13
movq %r13, %rdi
callq 0x9698
movq 0xe0(%rsp), %rdi
movq %r13, %rsi
callq 0x3460
movq 0x10(%rsp), %rdi
cmpq %rbx, %rdi
je 0xb567
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x33d0
movq 0x38(%rsp), %rax
cmpq $0x0, 0x70(%rax)
setne 0x60(%rax)
movzbl 0x1(%r15), %eax
subl %eax, %r14d
addl $-0x2, %r14d
cmpl $0x2, %r14d
movq 0x50(%rsp), %rbx
jl 0xb5a1
addq %rax, %r15
addq $0x2, %r15
movzbl 0x1(%r15), %eax
cmpl %eax, %r14d
jae 0xb342
leaq 0x60(%rsp), %r14
movq %r14, %rdi
leaq 0x6f08(%rip), %rsi      # 0x124b8
callq 0xa5b2
testb %al, %al
movq 0x38(%rsp), %r15
jne 0xb28c
cmpb $0x0, 0x60(%r15)
je 0xb5cf
movq 0x68(%r15), %rsi
jmp 0xb5d1
xorl %esi, %esi
movq %r14, %rdi
movq 0x30(%rsp), %rdx
movq %rbx, %rcx
xorl %r8d, %r8d
callq 0x5c14
cmpq $0x0, 0x2b8(%rax)
jne 0xb28c
addq $0x2b0, %rax            # imm = 0x2B0
addq $0x88, %r15
movq %rax, %rdi
movq %r15, %rsi
callq 0x31e0
jmp 0xb28c
movq 0x58(%rsp), %rdi
xorl %esi, %esi
callq 0x670d
jmp 0xaebe
jmp 0xb624
jmp 0xb624
movq %rax, %rbx
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
je 0xb643
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x33d0
movq %rbx, %rdi
callq 0x35d0
nop