domingo, 6 de mayo de 2007

Interfaz de red en Linux

En el siguiente ejemplo se muestra como acceder a la información de las interfaces de Linux en C:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sys/socket.h>
#include <sys/time.h>
#include <malloc.h>
#include <ctype.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <netinet/tcp.h>
#include <net/if.h>
#include <sys/ioctl.h>

#define ETH_P_ARP  0x0806

/* Funcion de utiliadad para pasar una ip en formato u_int32_t a un char* */
char *inetaddr ( u_int32_t ip )
{
struct in_addr in;
in.s_addr = ip;
return inet_ntoa(in);
}

int main ()
{
struct ifreq if_data;
int sockd;
u_int8_t  local_mac[6];
u_int32_t local_ip;
u_int32_t local_netmask;
u_int32_t local_broadcast;
u_int32_t ip;

/* Son necesarios privilegios de root */
if (getuid () != 0)
{
perror ("You must be root. \n");
exit (0);
}

/* Crea el socket */
if ((sockd = socket (AF_INET, SOCK_PACKET, htons (ETH_P_ARP))) < 0)
{
perror("socket");
exit (0);
}

/* Interfaz eth0 */
strcpy (if_data.ifr_name, "eth0");

/* Obtiene la MAC address */
if (ioctl (sockd, SIOCGIFHWADDR, &if_data) < 0)
{
perror ("ioctl(): SIOCGIFHWADDR \n");
exit(EXIT_FAILURE);
}
memcpy (local_mac, if_data.ifr_hwaddr.sa_data, 6);
printf ("MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
local_mac[0], local_mac[1], local_mac[2],
local_mac[3], local_mac[4], local_mac[5]);

/* Obtiene la IP address */
if (ioctl (sockd, SIOCGIFADDR, &if_data) < 0)
{
perror ("ioctl(); SIOCGIFADDR \n");
exit(EXIT_FAILURE);
}
memcpy ((void *) &ip, (void *) &if_data.ifr_addr.sa_data + 2, 4);
local_ip = ntohl (ip);
printf ("IP: %s\n", inetaddr(ip));

/* Obtiene la mascara de red */
if (ioctl (sockd, SIOCGIFNETMASK, &if_data) < 0)
{
perror ("ioctl(): SIOCGIFNETMASK \n");
exit(EXIT_FAILURE);
}
memcpy ((void *) &ip, (void *) &if_data.ifr_netmask.sa_data + 2, 4);
local_netmask = ntohl (ip);
printf ("NETMASK: %s\n", inetaddr(ip));

/* Obtiene la direccion de broadcast */
if (ioctl (sockd, SIOCGIFBRDADDR, &if_data) < 0)
{
perror ("ioctl(): SIOCGIFBRDADDR \n");
exit(EXIT_FAILURE);
}
memcpy ((void *) &ip, (void *) &if_data.ifr_broadaddr.sa_data + 2, 4);
local_broadcast = ntohl (ip);
printf ("BROADCAST: %s\n", inetaddr(ip));

return (0);
}