// File: /workspace/github_c_makefile_star2_O2/jfriesse[P]omping/rsfunc.c
// Function: rs_receive_msg
ssize_t
rs_receive_msg(int sock, struct sockaddr_storage *from_addr, char *msg, size_t msg_len,
    uint8_t *ttl, struct timeval *timestamp)
{
	char cmsg_buf[CMSG_SPACE(1024)];
	struct cmsghdr *cmsg;
	struct iovec msg_iovec;
	struct msghdr msg_hdr;
	ssize_t recv_size;
	int ittl;
	int timestamp_set;

	ittl = 0;
	timestamp_set = 0;

	memset(&msg_iovec, 0, sizeof(msg_iovec));
	msg_iovec.iov_base = msg;
	msg_iovec.iov_len = msg_len;

	memset(&msg_hdr, 0, sizeof(msg_hdr));
	msg_hdr.msg_name = from_addr;
	msg_hdr.msg_namelen = sizeof(struct sockaddr_storage);
	msg_hdr.msg_iov = &msg_iovec;
	msg_hdr.msg_iovlen = 1;
	msg_hdr.msg_control = cmsg_buf;
	msg_hdr.msg_controllen = sizeof(cmsg_buf);

	recv_size = recvmsg(sock, &msg_hdr, 0);

	if (recv_size == -1) {
		if (errno == EINTR) {
			DEBUG2_PRINTF("recvmsg error - EINTR");
			return (-2);
		}

		if (errno == EHOSTUNREACH || errno == EHOSTDOWN || errno == ENETDOWN ||
		    errno == ECONNRESET) {
			DEBUG2_PRINTF("recvmsg error - EHOSTUNREACH || EHOSTDOWN || ENETDOWN ||"
			    " ECONNRESET");
			return (-3);
		}

		DEBUG2_PRINTF("recvmsg error - errno = %d", errno);
		return (-1);
	}

	if (msg_hdr.msg_flags & MSG_TRUNC || msg_hdr.msg_flags & MSG_CTRUNC) {
		DEBUG2_PRINTF("recvmsg error - MSG_TRUNC | MSG_CTRUNC");
		return (-4);
	}

	for (cmsg = CMSG_FIRSTHDR(&msg_hdr); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg_hdr, cmsg)) {
		switch (cmsg->cmsg_level) {
		case SOL_SOCKET:
#ifdef SCM_TIMESTAMP
			if (cmsg->cmsg_type == SCM_TIMESTAMP &&
			    cmsg->cmsg_len >= sizeof(struct timeval) && timestamp != NULL) {
				memcpy(timestamp, CMSG_DATA(cmsg), sizeof(struct timeval));
				timestamp_set = 1;
			}
#endif
		case IPPROTO_IP:
			if (cmsg->cmsg_type == IP_TTL && cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
				memcpy(&ittl, CMSG_DATA(cmsg), sizeof(ittl));
			}
#ifdef IP_RECVTTL
			if (cmsg->cmsg_type == IP_RECVTTL && cmsg->cmsg_len > 1) {
				ittl = *(uint8_t *)CMSG_DATA(cmsg);
			}
#endif
			break;
		case IPPROTO_IPV6:
			if (cmsg->cmsg_type == IPV6_HOPLIMIT && cmsg->cmsg_len ==
			    CMSG_LEN(sizeof(int))) {
				memcpy(&ittl, CMSG_DATA(cmsg), sizeof(ittl));
			}
			break;
		}
	}

	*ttl = (uint8_t)ittl;

	if (!timestamp_set && timestamp != NULL) {
		*timestamp = util_get_time();
	}

	return (recv_size);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x468, %rsp            # imm = 0x468
movq %r9, %rbx
movq %r8, %r15
leaq 0x40(%rsp), %r8
movq %rdx, (%r8)
movq %rcx, 0x8(%r8)
xorps %xmm0, %xmm0
leaq 0x8(%rsp), %rax
movups %xmm0, 0x8(%rax)
movups %xmm0, 0x18(%rax)
movups %xmm0, 0x28(%rax)
movq %rsi, (%rax)
movl $0x80, 0x8(%rax)
movq %r8, 0x10(%rax)
movq $0x1, 0x18(%rax)
leaq 0x50(%rsp), %rcx
movq %rcx, 0x20(%rax)
movq $0x410, 0x28(%rax)      # imm = 0x410
movq %rax, %rsi
xorl %edx, %edx
callq 0x2280
cmpq $-0x1, %rax
je 0x71fe
testb $0x28, 0x38(%rsp)
je 0x723d
leaq 0x341a(%rip), %rdi      # 0xa5fb
leaq 0x34fe(%rip), %rcx      # 0xa6e6
pushq $0x3
popq %rdx
movl $0xb7, %esi
xorl %eax, %eax
callq 0x4998
pushq $-0x4
jmp 0x732b
callq 0x2060
movl (%rax), %r8d
leal -0x64(%r8), %eax
cmpl $0xd, %eax
ja 0x7252
movl $0x3011, %ecx           # imm = 0x3011
btl %eax, %ecx
jae 0x7252
leaq 0x33db(%rip), %rdi      # 0xa5fb
leaq 0x3460(%rip), %rcx      # 0xa687
pushq $0x3
popq %rdx
movl $0xae, %esi
xorl %eax, %eax
callq 0x4998
pushq $-0x3
jmp 0x732b
movq %rax, %r14
xorl %r13d, %r13d
cmpq $0x10, 0x30(%rsp)
jb 0x7280
movq 0x28(%rsp), %rax
jmp 0x7282
leaq 0x33a2(%rip), %rdi      # 0xa5fb
cmpl $0x4, %r8d
jne 0x7313
leaq 0x3407(%rip), %rcx      # 0xa671
pushq $0x3
popq %rdx
movl $0xa7, %esi
xorl %eax, %eax
callq 0x4998
pushq $-0x2
jmp 0x732b
xorl %eax, %eax
leaq 0x8(%rsp), %r12
xorl %ebp, %ebp
testq %rax, %rax
je 0x72f3
movl 0x8(%rax), %ecx
testl %ecx, %ecx
je 0x72ba
cmpl $0x29, %ecx
je 0x72c9
cmpl $0x1, %ecx
jne 0x72e6
cmpl $0x1d, 0xc(%rax)
jne 0x72ba
testq %rbx, %rbx
je 0x72ba
cmpq $0x10, (%rax)
jb 0x72ba
movups 0x10(%rax), %xmm0
movups %xmm0, (%rbx)
pushq $0x1
popq %rbp
movl 0xc(%rax), %ecx
cmpl $0xc, %ecx
je 0x72db
cmpl $0x2, %ecx
je 0x72cf
jmp 0x72e6
cmpl $0x34, 0xc(%rax)
jne 0x72e6
cmpq $0x14, (%rax)
jne 0x72e6
movl 0x10(%rax), %r13d
jmp 0x72e6
cmpq $0x2, (%rax)
jb 0x72e6
movzbl 0x10(%rax), %r13d
movq %r12, %rdi
movq %rax, %rsi
callq 0x2310
jmp 0x7289
testq %rbx, %rbx
sete %al
movb %r13b, (%r15)
testl %ebp, %ebp
setne %cl
orb %al, %cl
jne 0x732d
callq 0x8a18
movq %rax, (%rbx)
movq %rdx, 0x8(%rbx)
jmp 0x732d
leaq 0x33b1(%rip), %rcx      # 0xa6cb
pushq $0x3
popq %rdx
movl $0xb2, %esi
xorl %eax, %eax
callq 0x4998
pushq $-0x1
popq %r14
movq %r14, %rax
addq $0x468, %rsp            # imm = 0x468
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq