/*
 * Public Domain
 * Based on code from https://gist.github.com/OrangeTide/909204
 *
 * Original by Jon Mayo - August 22, 2006
 * This version written by Remilia Scarlet, 27 May 2021
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <sys/socket.h>
#include <netdb.h>

char* get_address(int fd, const char* name) {
	struct ifreq ifreq;
    char* ret = NULL;
    ret = malloc(sizeof(char) * 128);

    memset(&ifreq, 0, sizeof ifreq);
	strncpy(ifreq.ifr_name, name, IFNAMSIZ);

	if(ioctl(fd, SIOCGIFADDR, &ifreq) != 0) {
        return NULL;
	}

    switch(ifreq.ifr_addr.sa_family) {
    case AF_UNSPEC:
        return NULL;
    case AF_INET:
    case AF_INET6:
        getnameinfo(&ifreq.ifr_addr, sizeof ifreq.ifr_addr, ret, sizeof(char) * 128, 0, 0, NI_NUMERICHOST);
        return ret;
    default:
        return NULL;
	}
}

int get_addresses(int fd, char** ret) {
    struct ifreq* ifreq;
    struct ifconf ifconf;
    char buf[16384];
    size_t len;
    int addrNum = 0;

    ifconf.ifc_len = sizeof(buf);
    ifconf.ifc_buf = buf;
    if(ioctl(fd, SIOCGIFCONF, &ifconf) != 0) {
        ret = NULL;
        return -1;
    }

    ifreq = ifconf.ifc_req;

    for(int i = 0; i < ifconf.ifc_len; ) {
        len = sizeof(*ifreq);
        char* addr = get_address(fd, ifreq->ifr_name);
        if(addr) {
            ret[addrNum] = addr;
            addrNum++;
        }

        ifreq = (struct ifreq*)((char*)ifreq + len);
        i += len;
    }

    return addrNum;
}

/*
int main(int argc, char** argv) {
    char* addrs[16];
    int sockFD = 0;

	sockFD = socket(PF_INET, SOCK_DGRAM, 0);
    int numAddrs = get_addresses(sockFD, addrs);
    printf("Addrs: %i\n", numAddrs);

    for(int i = 0; i < numAddrs; i++) {
        printf("%s\n", addrs[i]);
    }

    return 0;
}
*/
