// File: /workspace/github_c_makefile_star2_O2/jfriesse[P]omping/sockfunc.c
// Function: sf_mcast_join_ssm_group
int
sf_mcast_join_ssm_group(const struct sockaddr *mcast_addr, const struct sockaddr *local_addr,
    const struct sockaddr *remote_addr, const char *local_ifname, int sock)
{
#ifdef IP_ADD_SOURCE_MEMBERSHIP
	struct ip_mreq_source mreq4;
#endif
#ifdef MCAST_JOIN_SOURCE_GROUP
	struct group_source_req greq;
	size_t addr_len;
	int iface_index;
	int ip_lv;
#endif

#ifdef IP_ADD_SOURCE_MEMBERSHIP
	if (mcast_addr->sa_family == AF_INET) {
		memset(&mreq4, 0, sizeof(mreq4));

		mreq4.imr_multiaddr = ((struct sockaddr_in *)mcast_addr)->sin_addr;
		mreq4.imr_interface = ((struct sockaddr_in *)local_addr)->sin_addr;
		mreq4.imr_sourceaddr = ((struct sockaddr_in *)remote_addr)->sin_addr;

		if (setsockopt(sock, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, &mreq4,
		    sizeof(mreq4)) == -1) {
			DEBUG_PRINTF("setsockopt IP_ADD_SOURCE_MEMBERSHIP failed");

			return (-1);
		}

		return (0);
	}
#endif

#ifdef MCAST_JOIN_SOURCE_GROUP
	if (mcast_addr->sa_family == AF_INET || mcast_addr->sa_family == AF_INET6) {
		iface_index = if_nametoindex(local_ifname);
		if (iface_index == 0) {
			DEBUG_PRINTF("if_nametoindex cannot convert iface name %s to index",
			    local_ifname);

			return (-1);
		}

		memset(&greq, 0, sizeof(greq));

		switch (mcast_addr->sa_family) {
		case AF_INET:
			addr_len = sizeof(struct sockaddr_in);
			ip_lv = IPPROTO_IP;
			break;
		case AF_INET6:
			addr_len = sizeof(struct sockaddr_in6);
			ip_lv = IPPROTO_IPV6;
			break;
		default:
			DEBUG_PRINTF("Unknown sockaddr family");
			errx(1, "Unknown sockaddr family");
			/* NOTREACHED */
		}

		greq.gsr_interface = iface_index;
		memcpy(&greq.gsr_group, mcast_addr, addr_len);
		memcpy(&greq.gsr_source, remote_addr, addr_len);

		if (setsockopt(sock, ip_lv, MCAST_JOIN_SOURCE_GROUP, &greq, sizeof(greq)) == -1) {
			DEBUG_PRINTF("setsockopt MCAST_JOIN_SOURCE_GROUP failed");

			return (-1);
		}

		return (0);
	}
#endif
	DEBUG_PRINTF("Can't join to Source-Specific Multicast because of no compile time support");
	errx(1, "Can't join to Source-Specific Multicast because of no compile time support");
	/* NOTREACHED */

	return (-1);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x118, %rsp            # imm = 0x118
movl %r8d, %ebp
movq %rdx, %r14
movq %rdi, %r15
movzwl (%rdi), %eax
cmpl $0xa, %eax
je 0x8155
cmpl $0x2, %eax
jne 0x8240
movl 0x4(%r15), %eax
leaq 0x10(%rsp), %rcx
movl %eax, (%rcx)
movl 0x4(%rsi), %eax
movl %eax, 0x4(%rcx)
movl 0x4(%r14), %eax
movl %eax, 0x8(%rcx)
xorl %ebx, %ebx
pushq $0x27
popq %rdx
pushq $0xc
popq %r8
movl %ebp, %edi
xorl %esi, %esi
callq 0x20c0
cmpl $-0x1, %eax
jne 0x822c
leaq 0x2908(%rip), %rdi      # 0xaa49
leaq 0x2988(%rip), %rcx      # 0xaad0
pushq $0x2
popq %rdx
movl $0x194, %esi            # imm = 0x194
jmp 0x8222
movq %rcx, %rbx
movq %rcx, %rdi
callq 0x21e0
testl %eax, %eax
je 0x8199
movl %eax, %r12d
leaq 0x10(%rsp), %rdi
xorl %ebx, %ebx
movl $0x108, %edx            # imm = 0x108
xorl %esi, %esi
callq 0x2150
movzwl (%r15), %eax
cmpl $0x2, %eax
je 0x81bb
cmpl $0xa, %eax
jne 0x8258
pushq $0x29
popq %rax
movl %eax, 0xc(%rsp)
pushq $0x1c
popq %r13
jmp 0x81c7
leaq 0x28a9(%rip), %rdi      # 0xaa49
leaq 0x26db(%rip), %rcx      # 0xa882
pushq $0x2
popq %rdx
movl $0x1a2, %esi            # imm = 0x1A2
movq %rbx, %r8
xorl %eax, %eax
callq 0x4998
jmp 0x8229
pushq $0x10
popq %r13
movl $0x0, 0xc(%rsp)
leaq 0x18(%rsp), %rdi
movl %r12d, -0x8(%rdi)
movq %r15, %rsi
movq %r13, %rdx
callq 0x2200
leaq 0x98(%rsp), %rdi
movq %r14, %rsi
movq %r13, %rdx
callq 0x2200
pushq $0x2e
popq %rdx
leaq 0x10(%rsp), %rcx
movl %ebp, %edi
movl 0xc(%rsp), %esi
movl $0x108, %r8d            # imm = 0x108
callq 0x20c0
cmpl $-0x1, %eax
jne 0x822c
leaq 0x2836(%rip), %rdi      # 0xaa49
leaq 0x28e1(%rip), %rcx      # 0xaafb
pushq $0x2
popq %rdx
movl $0x1bd, %esi            # imm = 0x1BD
xorl %eax, %eax
callq 0x4998
pushq $-0x1
popq %rbx
movl %ebx, %eax
addq $0x118, %rsp            # imm = 0x118
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x2802(%rip), %rdi      # 0xaa49
leaq 0x28d7(%rip), %rbx      # 0xab25
pushq $0x2
popq %rdx
movl $0x1c5, %esi            # imm = 0x1C5
jmp 0x826e
leaq 0x27ea(%rip), %rdi      # 0xaa49
leaq 0xe77(%rip), %rbx       # 0x90dd
pushq $0x2
popq %rdx
movl $0x1b3, %esi            # imm = 0x1B3
movq %rbx, %rcx
xorl %eax, %eax
callq 0x4998
pushq $0x1
popq %rdi
movq %rbx, %rsi
xorl %eax, %eax
callq 0x20f0
nopl (%rax)