// File: /workspace/github_c_makefile_star2_O3/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 $0x108, %rsp            # imm = 0x108
movl %r8d, %ebp
movq %rdx, %r14
movq %rdi, %r15
movzwl (%rdi), %eax
cmpl $0xa, %eax
je 0x8529
cmpl $0x2, %eax
jne 0x861b
movl 0x4(%r15), %eax
movq %rsp, %rcx
movl %eax, (%rcx)
movl 0x4(%rsi), %eax
movl %eax, 0x4(%rcx)
movl 0x4(%r14), %eax
movl %eax, 0x8(%rcx)
xorl %ebx, %ebx
movl %ebp, %edi
xorl %esi, %esi
movl $0x27, %edx
movl $0xc, %r8d
callq 0x20c0
cmpl $-0x1, %eax
jne 0x8607
leaq 0x3531(%rip), %rdi      # 0xba49
leaq 0x35b1(%rip), %rcx      # 0xbad0
movl $0x194, %esi            # imm = 0x194
jmp 0x85d2
movq %rcx, %rbx
movq %rcx, %rdi
callq 0x21e0
testl %eax, %eax
je 0x85e0
movl %eax, %r12d
movq %rsp, %rdi
xorl %ebx, %ebx
movl $0x108, %edx            # imm = 0x108
xorl %esi, %esi
callq 0x2150
movzwl (%r15), %eax
movl $0x10, %r13d
movl $0x0, %ecx
cmpl $0x2, %eax
je 0x8578
cmpl $0xa, %eax
jne 0x8630
movl $0x29, %ecx
movl $0x1c, %r13d
leaq 0x8(%rsp), %rdi
movl %r12d, -0x8(%rdi)
movl %ecx, %r12d
movq %r15, %rsi
movq %r13, %rdx
callq 0x2200
leaq 0x88(%rsp), %rdi
movq %r14, %rsi
movq %r13, %rdx
callq 0x2200
movq %rsp, %rcx
movl %ebp, %edi
movl %r12d, %esi
movl $0x2e, %edx
movl $0x108, %r8d            # imm = 0x108
callq 0x20c0
cmpl $-0x1, %eax
jne 0x8607
leaq 0x3483(%rip), %rdi      # 0xba49
leaq 0x352e(%rip), %rcx      # 0xbafb
movl $0x1bd, %esi            # imm = 0x1BD
movl $0x2, %edx
xorl %eax, %eax
callq 0x4ad6
jmp 0x8602
leaq 0x3462(%rip), %rdi      # 0xba49
leaq 0x3294(%rip), %rcx      # 0xb882
movl $0x1a2, %esi            # imm = 0x1A2
movl $0x2, %edx
movq %rbx, %r8
xorl %eax, %eax
callq 0x4ad6
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movl %ebx, %eax
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x3427(%rip), %rdi      # 0xba49
leaq 0x34fc(%rip), %rbx      # 0xbb25
movl $0x1c5, %esi            # imm = 0x1C5
jmp 0x8643
leaq 0x3412(%rip), %rdi      # 0xba49
leaq 0x1a9f(%rip), %rbx      # 0xa0dd
movl $0x1b3, %esi            # imm = 0x1B3
movl $0x2, %edx
movq %rbx, %rcx
xorl %eax, %eax
callq 0x4ad6
movl $0x1, %edi
movq %rbx, %rsi
xorl %eax, %eax
callq 0x20f0
nopl (%rax)