PDA

View Full Version : ioctl request to get the HW address



threahdead
08-10-2003, 11:07 AM
hi heres my sample 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

threahdead
08-10-2003, 11:29 AM
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?



#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);
}

lsme
08-11-2003, 05:19 AM
Try this programe.



#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;
}

threahdead
08-11-2003, 08:19 AM
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

lsme
08-12-2003, 05:04 AM
#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)

threahdead
08-13-2003, 06:22 AM
thanks

tuomaskk
01-02-2008, 07:59 PM
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.



#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

Salem
01-03-2008, 01:34 AM
4.5 year bump - read the rules - closed.