Obteniendo información de la interfaz de red desde C.
Bueno, en el siguiente ejemplo muestro como puede obtenerse la Hardware address (dirección MAC)de una placa de red ethernet en un sistema linux.
Si bien el código parece algo intimidante al principio, conforme la pelea avanza uno se va amigando, hasta finalmente entenderlo.
La idea es sencilla: se levanta un socket (uso "socket ()"), sobre el cual utilizamos "ioctl()" para preguntar la dirección de hardware. ioctl no sirve solo para esta función, esta es una genérica del sistema operativo, que nos permite interactuar con los ficheros especiales (dispositivos) para obtener y setear paramétros específicos de configuración. por ejemplo lo que hacemos aquí es preguntar por la dirección hardware; otro ejemplo pordría ser abrir la lectora de dvd, etc.
Dejando de lado las palabras, pongo el código:
para compilar simplemente poner el codigo en "ethaddr.c" y luego:
$ gcc ethaddr.c -o ethaddr
Bueno, espero que le sea de utilidad a alguien.
Referencias:
man socket (2)
man ioctl (2)
man netdevice (7)
Si bien el código parece algo intimidante al principio, conforme la pelea avanza uno se va amigando, hasta finalmente entenderlo.
La idea es sencilla: se levanta un socket (uso "socket ()"), sobre el cual utilizamos "ioctl()" para preguntar la dirección de hardware. ioctl no sirve solo para esta función, esta es una genérica del sistema operativo, que nos permite interactuar con los ficheros especiales (dispositivos) para obtener y setear paramétros específicos de configuración. por ejemplo lo que hacemos aquí es preguntar por la dirección hardware; otro ejemplo pordría ser abrir la lectora de dvd, etc.
Dejando de lado las palabras, pongo el código:
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <string.h>
#define SUCCESS 0
/* La siguiente macro recibe como parametros:
* struct sockaddr * sockaddr_ptr;
* char * char_ptr;
* Retorna la direccion MAC, formateada de a dos valores hexadecimales
* separados por putos: 00:AF:...
*/
#define GET_HW_ADDR_STRING(sockaddr_ptr, charptr) \
snprintf (charptr, 18, "%02X:%02X:%02X:%02X:%02X:%02X", \
(unsigned char) sockaddr_ptr->sa_data[0], \
(unsigned char) sockaddr_ptr->sa_data[1], \
(unsigned char) sockaddr_ptr->sa_data[2], \
(unsigned char) sockaddr_ptr->sa_data[3], \
(unsigned char) sockaddr_ptr->sa_data[4], \
(unsigned char) sockaddr_ptr->sa_data[5])
unsigned long get_hw_addr (struct ifreq * ifdata);
int main (int argc, char ** argv)
{
struct ifreq request;
struct sockaddr * addr;
char string_addr[18];
int fd=0, query_result=0;
if (argc != 2)
{
printf ("MODO DE USO: %s interfaz ethernet.\n",argv[0]);
printf ("Imprime la direccion de hardware de la interfaz seleccionada.\n");
printf ("Ej: %s eth0\n",argv[0]);
return 1;
}
fd = socket (PF_INET, SOCK_STREAM, 0);
if (fd == -1)
{
perror ("No puedo abrir socket.");
return 1;
}
strncpy((char*)request.ifr_name,(char*)argv[1],IFNAMSIZ);
/* La siguiente llamada hace la magia negra.
* Para ver todos los ioctls: man netdevice.
* De esta forma se pueden realizar muchas operaciones con nuestra
* interfaz (seteo de mac addr, get de metrica,...).
*/
query_result = ioctl (fd, SIOCGIFHWADDR, &request);
if (query_result !=0)
{
perror ("No puedo obtener la informacion de la interfaz seleccionada");
return 1;
}
close (fd);
addr= &(request.ifr_hwaddr);
GET_HW_ADDR_STRING (addr, string_addr);
printf("HWAddr: %s\n", string_addr);
return SUCCESS;
}
para compilar simplemente poner el codigo en "ethaddr.c" y luego:
$ gcc ethaddr.c -o ethaddr
Bueno, espero que le sea de utilidad a alguien.
Referencias:
man socket (2)
man ioctl (2)
man netdevice (7)
Etiquetas: C language, C programing, C programming, HWAddr, ioctl, linux network programing, linux network programming, network, programación, programing, programming, socket

0 comentarios:
Publicar un comentario en la entrada
Suscribirse a Enviar comentarios [Atom]
<< Página principal