// File: /workspace/github_cpp_makefile_star2_O1/yahoo[P]UDPing/src/ifinfo.cc
// Function: getIfInfo(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, int*, unsigned char*)
int getIfInfo (string ip, int* ifIndex, uint8_t *srcMac) {
    char interface [256];
    int sd;
    int foundInterface = 0;
    struct ifreq ifr;
    struct ifaddrs *ifa;
    struct in_addr srcAddr;

    cout << "Getting interface info for " << ip << endl;

    if (inet_pton (AF_INET, ip.c_str(), &srcAddr) != 1) {
         perror ("inet_pton failed");
         return (-1);
    }

    getifaddrs(&ifa);
    struct ifaddrs *curAddr = ifa;
    while (curAddr) {
        struct sockaddr_in* sin = (struct sockaddr_in *) curAddr->ifa_addr;
        if (sin->sin_addr.s_addr == srcAddr.s_addr) {
            printf ("The interface is named %s\n", curAddr->ifa_name);
            strcpy (interface, curAddr->ifa_name);
            foundInterface = 1;
            break;
        }
        curAddr = curAddr->ifa_next;
    }
    freeifaddrs(ifa);

    if (!foundInterface) {
        cerr << "Couldn't find interface for IP " << ip << endl;
        return (-1);
    }

    if ((sd = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 0) {
        perror ("socket() failed to get socket descriptor for using ioctl() ");
        return (-1);
    }

    // Use ioctl() to look up interface name and get its MAC address.
    memset (&ifr, 0, sizeof (ifr));
    snprintf (ifr.ifr_name, sizeof (ifr.ifr_name), "%s", interface);
    if (ioctl (sd, SIOCGIFHWADDR, &ifr) < 0) {
        perror ("ioctl() failed to get source MAC address ");
        return (-1);
    }
    close (sd);

    // Copy source MAC address.
    memcpy (srcMac, ifr.ifr_hwaddr.sa_data, 6 * sizeof (uint8_t));
    
    // Report source MAC address to stdout.
    printf ("MAC address is ");
    for (int i=0; i<5; i++) {
        printf ("%02x:", srcMac[i]);
    }
    printf ("%02x\n", srcMac[5]);
    
    // Find interface index from interface name and store index in
    // struct sockaddr_ll device, which will be used as an argument of sendto().
    if ((*ifIndex = if_nametoindex (interface)) == 0) {
        perror ("if_nametoindex() failed to obtain interface index ");
        return (-1);
    }
    printf ("Index is %i\n", *ifIndex);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x168, %rsp            # imm = 0x168
movq %rdx, %r14
movq %rsi, %rbx
movq %rdi, %r15
movq 0x344b(%rip), %r12      # 0x7fd0
leaq 0xcdc(%rip), %rsi       # 0x5868
movl $0x1b, %edx
movq %r12, %rdi
callq 0x22e0
movq (%r15), %rsi
movq 0x8(%r15), %rdx
movq %r12, %rdi
callq 0x22e0
movq %rax, %r12
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x22a0
movsbl %al, %esi
movq %r12, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x21a0
movq (%r15), %rsi
leaq 0xc(%rsp), %rdx
movl $0x2, %edi
callq 0x2460
cmpl $0x1, %eax
jne 0x4cda
movq %r15, 0x20(%rsp)
movq %r14, 0x10(%rsp)
movq %rbx, 0x18(%rsp)
leaq 0x28(%rsp), %r12
movq %r12, %rdi
callq 0x2450
movq (%r12), %rbp
leaq 0xc81(%rip), %r12       # 0x5895
leaq 0x60(%rsp), %r13
xorl %ebx, %ebx
testq %rbp, %rbp
je 0x4c5c
movq 0x18(%rbp), %rax
movl 0x4(%rax), %r14d
movl 0xc(%rsp), %r15d
cmpl %r15d, %r14d
jne 0x4c53
movq 0x8(%rbp), %rsi
movq %r12, %rdi
xorl %eax, %eax
callq 0x2060
movq 0x8(%rbp), %rsi
movq %r13, %rdi
callq 0x2270
movl $0x1, %ebx
jmp 0x4c57
movq (%rbp), %rbp
cmpl %r15d, %r14d
jne 0x4c1b
movq 0x28(%rsp), %rdi
callq 0x23f0
testl %ebx, %ebx
jne 0x4ce6
movq 0x337f(%rip), %rbx      # 0x7ff0
leaq 0xc38(%rip), %rsi       # 0x58b0
movl $0x1f, %edx
movq %rbx, %rdi
callq 0x22e0
movq 0x20(%rsp), %rax
movq (%rax), %rsi
movq 0x8(%rax), %rdx
movq %rbx, %rdi
callq 0x22e0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x22a0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x21a0
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x168, %rsp            # imm = 0x168
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xba3(%rip), %rdi       # 0x5884
jmp 0x4dd9
movl $0x11, %edi
movl $0x3, %esi
movl $0x300, %edx            # imm = 0x300
callq 0x20d0
testl %eax, %eax
jns 0x4d0a
leaq 0xbcb(%rip), %rdi       # 0x58d0
jmp 0x4dd9
movl %eax, %ebp
xorps %xmm0, %xmm0
leaq 0x30(%rsp), %r15
movaps %xmm0, 0x10(%r15)
movaps %xmm0, (%r15)
movq $0x0, 0x20(%r15)
leaq 0xbe0(%rip), %rdx       # 0x590c
leaq 0x60(%rsp), %rcx
movl $0x10, %esi
movq %r15, %rdi
xorl %eax, %eax
callq 0x23c0
movl $0x8927, %esi           # imm = 0x8927
movl %ebp, %edi
movq %r15, %rdx
xorl %eax, %eax
callq 0x2360
testl %eax, %eax
jns 0x4d5e
leaq 0xbb3(%rip), %rdi       # 0x590f
jmp 0x4dd9
movl %ebp, %edi
callq 0x2470
movl 0x42(%rsp), %eax
movq 0x10(%rsp), %r14
movl %eax, (%r14)
movzwl 0x46(%rsp), %eax
movw %ax, 0x4(%r14)
leaq 0xbb7(%rip), %rdi       # 0x5939
xorl %eax, %eax
callq 0x2060
leaq 0xbb9(%rip), %r15       # 0x5949
xorl %ebx, %ebx
movzbl (%r14,%rbx), %esi
movq %r15, %rdi
xorl %eax, %eax
callq 0x2060
incq %rbx
cmpq $0x5, %rbx
jne 0x4d92
movzbl 0x5(%r14), %esi
leaq 0xb99(%rip), %rdi       # 0x594f
xorl %eax, %eax
callq 0x2060
leaq 0x60(%rsp), %rdi
callq 0x20b0
movq 0x18(%rsp), %rcx
movl %eax, (%rcx)
testl %eax, %eax
jne 0x4de3
leaq 0xb7c(%rip), %rdi       # 0x5955
callq 0x2210
jmp 0x4cc3
leaq 0xb9e(%rip), %rdi       # 0x5988
movl %eax, %esi
xorl %eax, %eax
callq 0x2060