Thread: ioctl request to get the HW address

  1. #1
    template<typename T> threahdead's Avatar
    Join Date
    Sep 2002
    Posts
    214

    ioctl request to get the HW address

    hi heres my sample code

    Code:
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <sys/ioctl.h>
    
    int main (void)
    {
        int sockfd;
        int io;
        char buffer[1024];
        
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if(sockfd < 0){
    	perror("socket");
    	exit(1);
        }
        
        io = ioctl(sockfd, SIOCGIFHWADDR, (char *)buffer);
        if(io < 0){
    	perror("ioctl");
    	exit(1);
        }
        
        printf("fetched HW address with ioctl on sockfd.\n");
        printf("HW address of interface is: %s\n", buffer);
    
        exit(0);
    }
    why am i getting a "bad address" error with ioctl?
    i found the constant used with the ioctl in bits/ioctls.h.

    sockfd is obviously a socket but why isnt it working?

    thanks

  2. #2
    template<typename T> threahdead's Avatar
    Join Date
    Sep 2002
    Posts
    214
    ok i figured out what the third argument must be when requesting the hw address of an interface.

    heres the fixed code, with this code i still get an error message: no such device.

    why isnt this working out?
    do i have to fill something in the ifreq structure?

    Code:
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <sys/ioctl.h>
    #include <net/if.h>
    #include <stdlib.h>
    
    int main (void)
    {
        int sockfd;
        int io;
        struct ifreq *interf;
        /* SIOCGIFHWADDR
        Gets the interface hardware address. argp points to an ifreq structure.
       */
        interf = (struct ifreq *)malloc(sizeof(struct ifreq));
        
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if(sockfd < 0){
    	perror("socket");
    	exit(1);
        }
        
        io = ioctl(sockfd, SIOCGIFHWADDR, interf);
        if(io < 0){
    	perror("ioctl");
    	exit(1);
        }
    
        exit(0);
    }

  3. #3
    Registered User
    Join Date
    Feb 2003
    Posts
    16
    Try this programe.

    Code:
    #include <sys/ioctl.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <net/if.h>
    #include <arpa/inet.h>
    
    #include <unistd.h>
    #include <stdio.h>
    #define MAX_IFS 64
    
    int main()
    {
        struct ifreq *ifr, *ifend;
        struct ifreq ifreq;
        struct ifconf ifc;
        struct ifreq ifs[MAX_IFS];
        int SockFD;
    
    
        SockFD = socket(AF_INET, SOCK_DGRAM, 0);
    
    
        ifc.ifc_len = sizeof(ifs);
        ifc.ifc_req = ifs;
        if (ioctl(SockFD, SIOCGIFCONF, &ifc) < 0)
        {
            printf("ioctl(SIOCGIFCONF): %m\n");
            return 0;
        }
    
    
        ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
        for (ifr = ifc.ifc_req; ifr < ifend; ifr++)
        {
            if (ifr->ifr_addr.sa_family == AF_INET)
            {
                strncpy(ifreq.ifr_name, ifr->ifr_name,sizeof(ifreq.ifr_name));
                if (ioctl (SockFD, SIOCGIFHWADDR, &ifreq) < 0)
                {
                  printf("SIOCGIFHWADDR(%s): %m\n", ifreq.ifr_name);
                  return 0;
                }
    
    
          printf("Device %s -> Ethernet %02x:%02x:%02x:%02x:%02x:%02x\n", ifreq.ifr_name,
          (int) ((unsigned char *) &ifreq.ifr_hwaddr.sa_data)[0],
          (int) ((unsigned char *) &ifreq.ifr_hwaddr.sa_data)[1],
          (int) ((unsigned char *) &ifreq.ifr_hwaddr.sa_data)[2],
          (int) ((unsigned char *) &ifreq.ifr_hwaddr.sa_data)[3],
          (int) ((unsigned char *) &ifreq.ifr_hwaddr.sa_data)[4],
          (int) ((unsigned char *) &ifreq.ifr_hwaddr.sa_data)[5]);
     }
        }
    
        return 0;
    }

  4. #4
    template<typename T> threahdead's Avatar
    Join Date
    Sep 2002
    Posts
    214
    thanks for the sample code, thisone works good.

    is it possible with an ioctl() request to find out the IP address of a given interface?
    i took a look in the bits/ioctls.h header but there was no constant that defined a request for the IP address.

    thanks

    EDIT: i found the matching code in the FAQ.
    ps: where can i find some more material about ioctl requests?

    thnx again
    Last edited by threahdead; 08-11-2003 at 08:30 AM.

  5. #5
    Registered User
    Join Date
    Feb 2003
    Posts
    16
    Code:
    #include <sys/ioctl.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <net/if.h>
    #include <arpa/inet.h>
    
    #include <unistd.h>
    #include <stdio.h>
    #define MAX_IFS 64
    
    int main()
    {
        struct ifreq *ifr, *ifend;
        struct ifreq ifreq;
        struct ifconf ifc;
        struct ifreq ifs[MAX_IFS];
        int SockFD;
    
    
        SockFD = socket(AF_INET, SOCK_DGRAM, 0);
    
    
        ifc.ifc_len = sizeof(ifs);
        ifc.ifc_req = ifs;
        if (ioctl(SockFD, SIOCGIFCONF, &ifc) < 0)
        {
            printf("ioctl(SIOCGIFCONF): %m\n");
            return 0;
        }
    
    
        ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
        for (ifr = ifc.ifc_req; ifr < ifend; ifr++)
        {
            if (ifr->ifr_addr.sa_family == AF_INET)
            {
                strncpy(ifreq.ifr_name, ifr->ifr_name,sizeof(ifreq.ifr_name));
                if (ioctl (SockFD, SIOCGIFHWADDR, &ifreq) < 0)
                {
                  printf("SIOCGIFHWADDR(%s): %m\n", ifreq.ifr_name);
                  return 0;
                }
    
    printf("Ip Address %s\n", inet_ntoa( ( (struct sockaddr_in *)  &ifr->ifr_addr)->sin_addr)); 
          printf("Device %s -> Ethernet %02x:%02x:%02x:%02x:%02x:%02x\n", ifreq.ifr_name,
          (int) ((unsigned char *) &ifreq.ifr_hwaddr.sa_data)[0],
          (int) ((unsigned char *) &ifreq.ifr_hwaddr.sa_data)[1],
          (int) ((unsigned char *) &ifreq.ifr_hwaddr.sa_data)[2],
          (int) ((unsigned char *) &ifreq.ifr_hwaddr.sa_data)[3],
          (int) ((unsigned char *) &ifreq.ifr_hwaddr.sa_data)[4],
          (int) ((unsigned char *) &ifreq.ifr_hwaddr.sa_data)[5]);
     }
        }
    
        return 0;
    }
    see man page netdevice(7)

  6. #6
    template<typename T> threahdead's Avatar
    Join Date
    Sep 2002
    Posts
    214
    thanks

  7. #7
    Registered User
    Join Date
    Jan 2008
    Posts
    1

    Post Correct way to get the eth0 hwaddr using ioctl

    Hello,

    I fixed your code. You will need to include the net/if.h and use the struct ifreq to pass the request info (fill in the eth0 for IF name first), and get the result in the same structure.

    Code:
    #include <sys/types.h> 
    #include <sys/socket.h> 
    #include <stdio.h> 
    #include <sys/ioctl.h> 
    #include <net/if.h>
    
    int main (void)  
    { 
      int sockfd; 
      int io; 
      char buffer[1024]; 
      struct ifreq ifr;
    
      sprintf(ifr.ifr_name, "eth0");
     
      sockfd = socket(AF_INET, SOCK_STREAM, 0); 
      if(sockfd < 0){ 
        perror("socket"); 
        exit(1); 
      } 
     
      io = ioctl(sockfd, SIOCGIFHWADDR, (char *)&ifr); 
      if(io < 0){ 
        perror("ioctl"); 
        exit(1); 
      } 
     
      printf("fetched HW address with ioctl on sockfd.\n"); 
      printf("HW address of interface is: %02X:%02X:%02X:%02X:%02X:%02X\n", 
        (unsigned char)ifr.ifr_ifru.ifru_hwaddr.sa_data[0],
        (unsigned char)ifr.ifr_ifru.ifru_hwaddr.sa_data[1],
        (unsigned char)ifr.ifr_ifru.ifru_hwaddr.sa_data[2],
        (unsigned char)ifr.ifr_ifru.ifru_hwaddr.sa_data[3],
        (unsigned char)ifr.ifr_ifru.ifru_hwaddr.sa_data[4],
        (unsigned char)ifr.ifr_ifru.ifru_hwaddr.sa_data[5]
      ); 
     
      exit(0); 
    }
    TuomasKK

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    4.5 year bump - read the rules - closed.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. What does this do (Windows API)?
    By EVOEx in forum Windows Programming
    Replies: 4
    Last Post: 12-19-2008, 10:48 AM
  2. Writing array, to file
    By zootreeves in forum C Programming
    Replies: 9
    Last Post: 09-08-2007, 05:06 PM
  3. I thought pointers were pointers...
    By keira in forum C Programming
    Replies: 19
    Last Post: 08-15-2007, 11:48 PM
  4. DX - CreateDevice - D3DERR_INVALIDCALL
    By Tonto in forum Game Programming
    Replies: 3
    Last Post: 12-01-2006, 07:17 PM
  5. Im so lost at . .
    By hermit in forum C Programming
    Replies: 18
    Last Post: 05-15-2002, 01:26 AM