Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ifreq's ifr_names are incorrect?

Tags:

c

macos

sockets

The following function determines if a given string is a valid network device name.


int isValidNDevice(char *name) {

    char data[4096];
    struct ifconf ifc;
    struct ifreq *ifr;
    int sk;
    int nIntfcs;

    sk = socket(AF_INET, SOCK_DGRAM, 0);
    if(sk < 0)
    {
        perror("socket");
        return 0;
    }

    ifc.ifc_len = sizeof(data);
    ifc.ifc_buf = (caddr_t)data;
    if(ioctl(sk, SIOCGIFCONF, &ifc) < 0)
    {
        perror("ioctl(SIOCGIFCONF)");
        return 0;
    }

    ifr = (struct ifreq*)data;
    nIntfcs = ifc.ifc_len / sizeof(struct ifreq);
    for(int i=0; i < nIntfcs; i++)
    {
        safe_printf("%s\n", (&ifr[i])->ifr_name);
        if (!strcmp((&ifr[i])->ifr_name, name)) {
            return 1;
        }
    }

    return 0;
}

When I run this function, I receive the following output.


lo0

stf0

�2�>S

en1j

0


This code worked fine a few months ago. What has changed? Am I doing something incorrectly?

OS: OSX El Capitan

like image 993
maelswarm Avatar asked Sep 12 '16 20:09

maelswarm


1 Answers

The array of structures returned by the SIOCGIFCONF IOCTL are not of the same size in OSX. They will have a field ifr->ifr_addr.sa_lenwhich will be different for each structure

Modified function to take care of this. Hope it helps:

int isValidNDevice(char *name) {

    char data[4096];
    struct ifconf ifc;
    struct ifreq *ifr;
    int sk,length;

    sk = socket(AF_INET, SOCK_DGRAM, 0);
    if(sk < 0)
    {
        perror("socket");
        return 0;
    }

    ifc.ifc_len = sizeof(data);
    ifc.ifc_buf = (caddr_t)data;
    if(ioctl(sk, SIOCGIFCONF, &ifc) < 0)
    {
        perror("ioctl(SIOCGIFCONF)");
        return 0;
    }

    ifr = (struct ifreq*)data;
    for(int i=0;i<ifc.ifc_len;)
    {
        length=IFNAMSIZ + ifr->ifr_addr.sa_len;
        printf("%s\n", ifr->ifr_name);
        if (!strcmp(ifr->ifr_name,name)) {
            printf("Interface Found!\n");
            return 1;
        }
        ifr=(struct ifr*)((char*)ifr+length);
        i+=length;
    }

    return 0;
}
like image 81
hashdefine Avatar answered Sep 21 '22 16:09

hashdefine