Aparecido con la versión 2.0 de la plataforma, allá por 2005, el espacio de nombres System.Net.NetworkInformation resulta de gran utilidad a la hora de crear aplicaciones de diagnóstico de red basadas en la plataforma .NET. Gracias a las clases contenidas en éste podemos obtener información de todo tipo acerca de nuestros dispositivos de comunicaciones (tarjetas de red y otros adaptadores) de forma que resultaría fácil clonar algunas herramientas de diagnóstico del sistema operativo para adaptarlas a nuestras necesidades. En su día, ya hace muchos años, comenté lo fácil que era construir un clon de "ping.exe" para determinar el estado de un servidor remoto (si responde o no). También es sencillo responder a cambios en la conectividad con los eventos de la clase NetworkChange, como también expliqué en su momento, lo cual nos permite detectar cambios en la dirección IP o que se pierda la conexión a Internet por ejemplo.

Direcciones MAC

Ayer, para un experimento, estuve construyendo una pseudo-clon básico de la utilidad "ipConfig.exe" que viene con Windows (en concreto el resultado de ipconfig /all). En realidad la parte que me interesaba era la obtención de la dirección física de las tarjetas de red, lo que coloquialmente se denomina Dirección MAC.

Las direcciones "Media Access Control" (MAC) son las direcciones físicas de los adaptadores de red, independientes de protocolos y otros factores superiores, ya que se trata de números únicos en el mundo asociados a cada tarjeta de red y grabados físicamente en éstas por el fabricante. De modo que comprobando las direcciones MAC podemos estar seguros de que estamos en un determinado sistema o no (enseguida las salvedades a esto). Es más, generalmente todas las tarjetas de red llevan su MAC impresa en una etiqueta para que podamos verla a simple vista:

MACEnTarjeta

 

La mayoría de los routers inalámbricos del mercado permiten hacer un filtro por MAC de modo que sólo las tarjetas de red que estén en una lista de MACs concreta puedan conectarse a dicha red. Si bien esto detendrá a los script-kiddies y otros posibles atacantes con poca idea, no sirve de mucho a la hora de protegernos de verdad ya que cualquier hacker avezado puede determinar alguna MAC válida analizando el tráfico inalámbrico y falseando la dirección MAC de su tarjeta de red, el llamado "mac spoofing", algo muy fácil de hacer en todos los sistemas operativos. En las maquinas virtuales (por ejemplo en Hyper-V o Virtual Box) es muy sencillo asignar cualquier dirección MAC que elijamos a una tarjeta de red virtual, por lo que podríamos emular cualquier tarjeta de red del mundo muy fácilmente. Por ejemplo, esta es la de un Linux Fedora virtualizado que tengo bajo Virtual Box:

MACEnVirtualBox

Las MAC pueden ser utilizadas también para licenciar un software de modo que sólo pueda ejecutarse en un determinado equipo (atándolo a sus tarjetas de red). Este es el motivo, por ejemplo, de que si cambiamos de tarjeta de red en nuestro equipo tengamos que volver a activar Windows, si bien no es el único factor físico que controla el sistema de licenciamiento de Microsoft.

El código de ejemplo

A continuación dejo el código fuente de un pequeño programa que, haciendo uso del espacio de nombres NetworkInformation, muestra información sobre todos los adaptadores de red de nuestro equipo, incluyendo sus direcciones MAC:

   1: using System;
   2: using System.Net.NetworkInformation;
   3:  
   4: public class InfoTarjetasRed
   5: {
   6:     //Entrada a la aplicación de consola
   7:     public static void Main()
   8:     {
   9:         try
  10:         {
  11:             MuestraInfoTarjetasRed();
  12:         }
  13:         catch (Exception e)
  14:         {
  15:             string error = string.Format("---\nSe ha producido el siguiente error:\n{0}\n---", e.ToString());
  16:             Console.WriteLine(error);
  17:         }
  18:         finally
  19:         {
  20:             Console.Write("Pulsa cualquier tecla para continuar...");
  21:             Console.ReadKey();
  22:         }
  23:     }
  24:  
  25:     private static void MuestraInfoTarjetasRed()
  26:     {
  27:         //Obtengo el nombre del ordenador y el dominio actuales
  28:         IPGlobalProperties propsOrdenador = IPGlobalProperties.GetIPGlobalProperties();
  29:         Console.WriteLine("Información de los interfaces de red de: {0}.{1}", propsOrdenador.HostName, propsOrdenador.DomainName);
  30:         Console.WriteLine("\n\tNombre de host ...........: {0}", propsOrdenador.HostName);
  31:         
  32:         //Info de las tarjetas de red
  33:         NetworkInterface[] tarjetas = NetworkInterface.GetAllNetworkInterfaces();
  34:         if (tarjetas == null || tarjetas.Length < 1)
  35:         {
  36:             Console.WriteLine("No se han encontrado tarjetas de red");
  37:             return;
  38:         }
  39:         
  40:         //Recorremos las propiedades de cada tarjeta
  41:         foreach (NetworkInterface tarjeta in tarjetas)
  42:         {
  43:             //Nombre de la tarjeta
  44:             Console.WriteLine("\n{0}:",tarjeta.Name);
  45:             Console.WriteLine("  Descripción .............. : {0}", tarjeta.Description);
  46:             Console.WriteLine("  Tipo de interfaz ......... : {0}", tarjeta.NetworkInterfaceType);
  47:             Console.WriteLine("  Velocidad ................ : {0:n}", tarjeta.Speed);
  48:             Console.WriteLine("  Estado ................... : {0}", tarjeta.OperationalStatus);
  49:             Console.WriteLine("  Soporta Multicast ........ : {0}", tarjeta.SupportsMulticast);
  50:             Console.WriteLine("  Dirección física (MAC) ... : {0}", ObtenMACLegible(tarjeta.GetPhysicalAddress().GetAddressBytes()));
  51:             
  52:             //Propiedades de protocolos
  53:             IPInterfaceProperties propiedades = tarjeta.GetIPProperties();
  54:             //IPv6?
  55:             bool soportaIPv6 = tarjeta.Supports(NetworkInterfaceComponent.IPv6);
  56:             Console.WriteLine("  ¿Soporta IPv6? ........... : {0}", soportaIPv6);
  57:         }
  58:     }
  59:     
  60:     //Pasamos los bytes de la dirección física a Hexadecimal para mostrarlos como MAC
  61:     private static string ObtenMACLegible(byte[] bytes)
  62:     {
  63:         string MAC = "";
  64:         for(int i = 0; i< bytes.Length; i++)
  65:         {
  66:             MAC += String.Format("{0}", bytes[i].ToString("X2"));
  67:             // Se mete un guión tras cada byte excepto en el último
  68:             if (i != bytes.Length -1)
  69:             {
  70:                 MAC += ("-");
  71:             }
  72:         }
  73:         return MAC;
  74:     }
  75: }

Lo único que se hace para visualizar la MAC de un modo más legible es separar sus bytes con guiones y expresarlos en hexadecimal, que es la forma más común (método ObtenMACLegible del final).

El resultado por la consola es similar al siguiente (he cambiado las MAC por seguridad):

MACSalidaConsola

 

Te puedes descargar el código fuente y el ejecutable (InfoTarjetasRed.zip, 3.57 KB) para probarlo por tu cuenta. ¡Espero que te sea útil!

💪🏻 ¿Este post te ha ayudado?, ¿has aprendido algo nuevo?
Pues NO te pido que me invites a un café... Te pido algo más fácil y mucho mejor

Escrito por un humano, no por una IA