0

A MAC address is parsed into an array of bytes (macaddr). The bytes are printed with printf() one after another. The bytes are supposed to look as pairs of hexadecimal characters. But some of them are padded with f characters.

For example, for macaddr[3] it prints 'ffffffcc' rather than 'cc', i.e. 4 bytes instead of single byte. The rest of the array items are printed correctly (macaddr[0] = 00, macaddr[1] = AA, macaddr[2] = BB, etc.)

What's the problem? Please help me to figure out what's wrong with the program.

#include <stdio.h>
#include <net/if.h> // struct ifconf
#include <errno.h>
#include <libnet.h>
#include <pcap.h>
#include <stdlib.h>
#include <unistd.h>

int getmacaddr() ;

int main(int argc, char *argv[])
{
    getmacaddr();    
}

int getmacaddr()
{
    struct ifconf ifc;
    struct ifreq *ifr;
    int sfd;
    int i;
    int devnums;
    char macaddr[ETHER_ADDR_LEN];

    ifc.ifc_req = NULL;

    sfd = socket(AF_INET,SOCK_DGRAM,0);
    if(sfd == -1)
    {
        perror("socket : ");
        return -1;
    }

    // get ifc.ifc_len
    if(ioctl(sfd,SIOCGIFCONF,&ifc) == -1)
    {
        perror("ioctl - SIOCGIFCONF : ");
        return -1;
    }
    devnums = ifc.ifc_len / sizeof(struct ifreq);

    // malloc ifc.ifc_buf and get IFCONF list
    ifc.ifc_buf = malloc(ifc.ifc_len);
    memset(ifc.ifc_buf,0x0,ifc.ifc_len);

    if(ioctl(sfd,SIOCGIFCONF,&ifc) == -1)
    {
        perror("ioctl - SIOCGIFCONF : ");
        return -1;
    }


    for(i = 0; i < devnums; i++,ifc.ifc_req++)
    {
        // idfy dev
        if( strcmp(ifc.ifc_req->ifr_ifrn.ifrn_name,"lo") && ifc.ifc_req->ifr_ifrn.ifrn_name != 0)
        {
            ifr = ifc.ifc_req;

            // IP address
            struct sockaddr_in *a = (struct sockaddr_in *) &ifr->ifr_addr;
            printf("%s",inet_ntoa(a->sin_addr));
            printf("\n");

            //get IFHWADDR
            if(ioctl(sfd,SIOCGIFHWADDR,ifr) == -1)
            {
                perror("ioctl - SIOCGIFHWADDR : ");
                return -1;
            }            
        }
    }

    memcpy(macaddr,ifr->ifr_hwaddr.sa_data,sizeof(macaddr));
    for(i = 0; i < ETHER_ADDR_LEN; i++)
    {
        printf("%02x ",macaddr[i]);
    }
    printf("\n");

    close(sfd);
    //    free(ifc.ifc_buf);   <- ?? error

    return 0;
}

EDIT

I've replaced the following line:

printf("%02x ",macaddr[i]);

with

printf("%02x ", (macaddr[i] & 0xff));
LotoLo
  • 327
  • 4
  • 17
hwisang
  • 19
  • 4

1 Answers1

0

Try this:

printf("%02x ", (unsigned char)macaddr[i] & 0xff);

We specify the minimum field width in the format string. So to make sure that the value will look exactly as a single byte, you can leave only the first 16 bits by applying a bit mask.

Ruslan Osmanov
  • 20,486
  • 7
  • 46
  • 60
  • I solved the problem, but I still curious why macaddr[3] print 'ffffffcc'. anyway thank you very much! – hwisang Oct 01 '16 at 08:57
  • @black, hmm, there should be another issue. Could you update your post with the new code? – Ruslan Osmanov Oct 01 '16 at 09:01
  • I just replaced [printf("%02x ",macaddr[i]);] with [printf("%02x ", (macaddr[i] & 0xff));]. remainder is same. – hwisang Oct 01 '16 at 09:13
  • @black, that's really strange. I hope you don't mind I've edited your post. Original text is available in older revisions, if you find the changes wrong. – Ruslan Osmanov Oct 01 '16 at 09:24
  • With the previous version I could reproduce the issue (it printed `08 ffffffed ffffffb9 25 ffffffe9 56` on my local machine). After applying the mask, it prints `08 ed b9 25 e9 56`. – Ruslan Osmanov Oct 01 '16 at 09:29
  • I appreciate your edit. my post get better sentence. you are so kind. very very thank you!! – hwisang Oct 01 '16 at 09:42
  • oh, I find to solve it!! It's signed vs unsigned problem [link](http://stackoverflow.com/questions/6063039/mac-address-printing) It's all thanks to you. because my english is very poor, so I don't know what I search word. But after your rewrite, I can know search word to solving for this problem. thanks! – hwisang Oct 01 '16 at 10:02
  • @black, heh, signedness. Indeed. – Ruslan Osmanov Oct 01 '16 at 10:06