// File: /workspace/github_cpp_makefile_star2_O2/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 0x3b51(%rip), %rdi      # 0x7fd0
leaq 0x13c2(%rip), %rsi      # 0x5848
callq 0x22a0
movq %rax, %rdi
movq %r15, %rsi
callq 0x2220
movq %rax, %rdi
callq 0x2150
movq (%r15), %rsi
pushq $0x2
popq %rdi
leaq 0x4(%rsp), %rdx
callq 0x2420
cmpl $0x1, %eax
jne 0x4567
leaq 0x8(%rsp), %r12
movq %r12, %rdi
callq 0x2410
movl 0x4(%rsp), %eax
movq (%r12), %r12
testq %r12, %r12
je 0x4524
movq 0x18(%r12), %rcx
cmpl %eax, 0x4(%rcx)
jne 0x44c8
movq 0x8(%r12), %rsi
leaq 0x138e(%rip), %rdi      # 0x5875
xorl %eax, %eax
callq 0x2050
movq 0x8(%r12), %rsi
leaq 0x40(%rsp), %rdi
callq 0x2260
movq 0x8(%rsp), %rdi
callq 0x23c0
pushq $0x11
popq %rdi
pushq $0x3
popq %rsi
movl $0x300, %edx            # imm = 0x300
callq 0x20c0
testl %eax, %eax
jns 0x4575
leaq 0x138e(%rip), %rdi      # 0x58b0
jmp 0x456e
movq 0x8(%rsp), %rdi
callq 0x23c0
movq 0x3abb(%rip), %rdi      # 0x7ff0
leaq 0x1354(%rip), %rsi      # 0x5890
callq 0x22a0
movq %rax, %rdi
movq %r15, %rsi
callq 0x2220
movq %rax, %rdi
callq 0x2150
pushq $-0x1
popq %rax
addq $0x140, %rsp            # imm = 0x140
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
leaq 0x12f6(%rip), %rdi      # 0x5864
callq 0x2200
jmp 0x4554
movl %eax, %ebp
xorps %xmm0, %xmm0
leaq 0x10(%rsp), %r15
movaps %xmm0, 0x10(%r15)
movaps %xmm0, (%r15)
andq $0x0, 0x20(%r15)
leaq 0x1358(%rip), %rdx      # 0x58ec
pushq $0x10
popq %rsi
leaq 0x40(%rsp), %rcx
movq %r15, %rdi
xorl %eax, %eax
callq 0x23a0
movl $0x8927, %esi           # imm = 0x8927
movl %ebp, %edi
movq %r15, %rdx
xorl %eax, %eax
callq 0x2340
testl %eax, %eax
jns 0x45c4
leaq 0x132d(%rip), %rdi      # 0x58ef
jmp 0x456e
movl %ebp, %edi
callq 0x2430
movl 0x22(%rsp), %eax
movl %eax, (%r14)
movzwl 0x26(%rsp), %eax
movw %ax, 0x4(%r14)
leaq 0x1336(%rip), %rdi      # 0x5919
xorl %eax, %eax
callq 0x2050
leaq 0x1338(%rip), %r15      # 0x5929
xorl %r12d, %r12d
cmpq $0x5, %r12
je 0x460e
movzbl (%r14,%r12), %esi
movq %r15, %rdi
xorl %eax, %eax
callq 0x2050
incq %r12
jmp 0x45f4
movzbl 0x5(%r14), %esi
leaq 0x1315(%rip), %rdi      # 0x592f
xorl %eax, %eax
callq 0x2050
leaq 0x40(%rsp), %rdi
callq 0x20a0
movl %eax, (%rbx)
testl %eax, %eax
jne 0x463d
leaq 0x12fd(%rip), %rdi      # 0x5935
jmp 0x456e
leaq 0x1324(%rip), %rdi      # 0x5968
movl %eax, %esi
xorl %eax, %eax
callq 0x2050