// File: /workspace/github_cpp_makefile_star2_O3/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 %r12
pushq %rbx
subq $0x140, %rsp            # imm = 0x140
movq %rdx, %r14
movq %rsi, %rbx
movq %rdi, %r15
movq 0x3489(%rip), %r12      # 0x7fd0
leaq 0xd1a(%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 0x4(%rsp), %rdx
movl $0x2, %edi
callq 0x2460
cmpl $0x1, %eax
jne 0x4c97
leaq 0x8(%rsp), %r12
movq %r12, %rdi
callq 0x2450
movl 0x4(%rsp), %eax
movq (%r12), %r12
testq %r12, %r12
je 0x4c24
movq 0x18(%r12), %rcx
cmpl %eax, 0x4(%rcx)
jne 0x4bc0
movq 0x8(%r12), %rsi
leaq 0xcb6(%rip), %rdi       # 0x5895
xorl %eax, %eax
callq 0x2060
movq 0x8(%r12), %rsi
leaq 0x40(%rsp), %rdi
callq 0x2270
movq 0x8(%rsp), %rdi
callq 0x23f0
movl $0x11, %edi
movl $0x3, %esi
movl $0x300, %edx            # imm = 0x300
callq 0x20d0
testl %eax, %eax
jns 0x4ca5
leaq 0xcae(%rip), %rdi       # 0x58d0
jmp 0x4c9e
movq 0x8(%rsp), %rdi
callq 0x23f0
movq 0x33bb(%rip), %rbx      # 0x7ff0
leaq 0xc74(%rip), %rsi       # 0x58b0
movl $0x1f, %edx
movq %rbx, %rdi
callq 0x22e0
movq (%r15), %rsi
movq 0x8(%r15), %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 $0x140, %rsp            # imm = 0x140
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
leaq 0xbe6(%rip), %rdi       # 0x5884
callq 0x2210
jmp 0x4c82
movl %eax, %ebp
xorps %xmm0, %xmm0
leaq 0x10(%rsp), %r15
movaps %xmm0, 0x10(%r15)
movaps %xmm0, (%r15)
movq $0x0, 0x20(%r15)
leaq 0xc45(%rip), %rdx       # 0x590c
leaq 0x40(%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 0x4cf9
leaq 0xc18(%rip), %rdi       # 0x590f
jmp 0x4c9e
movl %ebp, %edi
callq 0x2470
movl 0x22(%rsp), %eax
movl %eax, (%r14)
movzwl 0x26(%rsp), %eax
movw %ax, 0x4(%r14)
leaq 0xc21(%rip), %rdi       # 0x5939
xorl %eax, %eax
callq 0x2060
leaq 0xc23(%rip), %r15       # 0x5949
xorl %r12d, %r12d
movzbl (%r14,%r12), %esi
movq %r15, %rdi
xorl %eax, %eax
callq 0x2060
incq %r12
cmpq $0x5, %r12
jne 0x4d29
movzbl 0x5(%r14), %esi
leaq 0xc02(%rip), %rdi       # 0x594f
xorl %eax, %eax
callq 0x2060
leaq 0x40(%rsp), %rdi
callq 0x20b0
movl %eax, (%rbx)
testl %eax, %eax
jne 0x4d70
leaq 0xbea(%rip), %rdi       # 0x5955
jmp 0x4c9e
leaq 0xc11(%rip), %rdi       # 0x5988
movl %eax, %esi
xorl %eax, %eax
callq 0x2060