sábado, 31 de diciembre de 2011

Subnetting en redes IP v4 Parte I

Una dirección IPv4 (IPv4 address) tiene una longitud de 32 bits que se considera única para cada host, esta dirección se escribe en formato binario de izquierda a derecha donde se considera que el bit más significativo es el bit más hacia la izquierda, una IPv4 tiene dos partes, la parte de red (netid) y la parte de host (hostid), originalmente el espacio de direcciones IP fue dividido en tres clases diferentes clase A, clase B y clase C, cada clase se distingue por los primeros bits iniciales o bits de prefijo, como en la siguiente tabla:



La clase A tiene bit de prefijo en 0 y es seguido por 7 bits para la parte de red y 24 bits restantes para la parte de host, la clase B tiene dos bits de prefijo el primero en 1 y el segundo en 0 seguido de 14 bits para la parte de red y de 16 bits para la parte de host, la clase C tiene tres bits de prefijo el primero y el segundo en 1 y el tercero en 0 por lo que tiene 21 bits para la parte de red y 8 bits para la parte de host, existen también las clases D y E las cuales se usa para multicasting y para experimentación respectivamente.

En un principio este esquema pareció ser suficiente para el tamaño de las redes, pero conforme la Internet fue creciendo en número de redes y hosts, este esquema presento deficiencias, una de ellas fue el desperdicio y el agotamiento de direcciones, por lo que una de las soluciones a este problema fue el concepto de subneteo (subnetting) el cual nos permite tomar una dirección de red y crear subconjuntos de esa red o bien subredes esto se logra mediante los siguientes pasos:


Por ejemplo si se nos pide subneteo en una red clase B y se nos da un mascara de 27 bits, la clase B tiene 16 bits para el campo de red y 16 bits para el campo de host.
Se resta el número de mascara menos el número de bits del campo de red y el resultado es el número de bits que debemos de tomar de los octetos del campo de host.
En este caso:



Se utilizan los 11 bits para el subneteo y los 5 bits restantes se utilizan para el campo de host. Por lo que quedaría de la siguiente forma:


Bien ahora que ya tenemos identificados los bits de subred, vamos a poner en práctica como lo obtenemos las subredes en forma decimal.

Supongamos que tenemos una red 130.3.0.0 con una subnet mask de 25 o 130.3.0.0/25


Si necesitamos encontrar los números de subredes: 25 y 400 respectivamente por lo que en principio calculamos el número de bits que necesitaremos para la subred por lo que hacemos la resta:

25-16 = 9 bits para subneteo

Esquematizamos los octetos de la red 130.3.0.0/25, para una mejor comprensión:


En la parte inferior entre el tercero y el cuarto octeto vemos en color verde el número de subredes correspondientes a cada bit de la parte de subred, para la representación del valor en decimal utilizamos los valores de la parte superior, por lo que la suma de cada bit encedido en la parte inferior nos proporcione como resultado el número de subred y la suma de sus valores en la parte superior nos proporcione la representación decimal , así por ejemplo la subred número 25 será:


Hay que distinguir que para el número de subred sumamos los valores que nos den como resultado el número de subred que buscamos, sin importar que se encuentren en diferentes octetos y que para la parte decimal su representación es únicamente la suma de los valores de los bits que componen ese octeto.

Encendemos los valores de subred del tercer octeto en 16 y 8 y el valor de 1 del cuarto octeto para que la suma de sus valores de subred tengamos el número de 25.

16 + 8 + 1 = 25
Ahora entonces sumamos la parte superior del tercer octeto para obtener su representación decimal en este caso:

8 + 4 = 12
Y para el último octeto la representación decimal del bit encendido nos da 128, por lo que juntando todos los octetos obtenemos que la subred 25 se represente por la dirección Ipv4:

130.3.12.128 / 25
Ahora buscamos la representación decimal de la subred 400 utilizando el mismo método



En este caso como es un número par de subred, inferimos que el último octeto no tendrá valor por lo que nos concentramos en los bits del tercer octeto, prendemos el bit de subred 256, el bit 128 y por último el bit 16 de la suma obtenemos los bits de la subred 400.

256 + 128 + 16 = 400
Ahora obtenemos la representación decimal de los bits prendidos en el tercer octeto.

128 + 64 + 8 = 200
La subred 400 queda representada en formato decimal como:

130.3.200.0/25

martes, 27 de diciembre de 2011

Entendiendo Satellite Assemblies usando MonoDevelop - (parte 2)

En la primera parte de este tutorial, se mostró como crear Satellite Assemblies, ahora en este segunda parte se mostrará un listado donde se muestra el código que nos mostrará los pasos de como consumir los ensamblados satélite o ensamblados de recursos desde una aplicación GTK#.


using System;
using Gtk;
using System.IO;
using System.Resources;
using Gdk;
using System.Reflection;

namespace TestResource
{
class MainClass : Gtk.Window
{
DrawingArea darea = null;
Label label1 = null;
Button btnLoad = null;
Pixmap pixmap;
Pixbuf pngbuf;
public MainClass():base("Test Resources"){
BorderWidth = 8;
this.DeleteEvent += new DeleteEventHandler(OnWindowDelete);
Frame frame = new Frame("Load");
Add(frame);
VBox MainPanel = new VBox (false, 8);
label1 = new Label("Query is: ");
darea = new DrawingArea();
btnLoad = new Button("Load resources");
btnLoad.Clicked += AddResource_Clicked;
darea.SetSizeRequest (200, 200);
darea.ExposeEvent += Expose_Event;
darea.ConfigureEvent += Configure_Event;
MainPanel.Add(label1);
MainPanel.PackStart(darea);
MainPanel.Add(btnLoad);
frame.Add (MainPanel);
SetDefaultSize (320, 233);
Resizable = false;
ShowAll();
}
public void OnWindowDelete(object o, DeleteEventArgs args) {
Application.Quit(); }

public static void Main (string[] args)
{
Application.Init();
new MainClass();
Application.Run();
}

void PlacePixbuf (Gdk.Pixbuf buf)
{
pixmap.DrawPixbuf (darea.Style.BlackGC,buf, 0, 0, 0, 0,buf.Width,
buf.Height,RgbDither.None, 0, 0);
darea.QueueDrawArea (0, 0, buf.Width, buf.Height);
}

void LoadResources(){
try{
//find the assembly
string assem = "demo.resources.dll";
Assembly assembly = Assembly.LoadFrom(assem);
if(File.Exists(assem))
{
//Instance for resourcemanager
ResourceManager rm = new ResourceManager("demo",assembly);
//get the string for the resource
label1.Text += rm.GetString("query1");
//get the image for the resource
System.Drawing.Bitmap bitmap = (System.Drawing.Bitmap)rm.GetObject("pugme");
bitmap.Save("pugme.png",System.Drawing.Imaging.ImageFormat.Png);
pngbuf = new Pixbuf("pugme.png");
}
}catch(Exception e){
Console.WriteLine(e.Message);
}
}

void Configure_Event (object obj, ConfigureEventArgs args)
{
Gdk.EventConfigure ev = args.Event;
Gdk.Window window = ev.Window;
Gdk.Rectangle allocation = darea.Allocation;
pixmap = new Gdk.Pixmap (window, allocation.Width,allocation.Height, -1);
pixmap.DrawRectangle (darea.Style.WhiteGC, true, 0, 0,allocation.Width,
allocation.Height);
}

void Expose_Event (object obj, ExposeEventArgs args)
{
Gdk.Rectangle area = args.Event.Area;
args.Event.Window.DrawDrawable (darea.Style.WhiteGC,
pixmap,area.X, area.Y,area.X, area.Y,area.Width, area.Height);
}

void AddResource_Clicked (object obj, EventArgs args)
{
LoadResources();
PlacePixbuf (pngbuf);
}
}
}

Toda esta funcionalidad se encuentra en el método LoadResources() , este método comienza primeramente con la carga en tiempo de ejecución del ensamblado que contiene los recursos utilizando las líneas siguientes:

string assem = "demo.resources.dll";
Assembly assembly = Assembly.LoadFrom(assem);

A continuación creamos una instancia de la clase ResourceManager en la cual se encuentran los métodos para obtener los recursos del ensamblado, en este ejemplo obtenemos un recurso de tipo cadena y otro de tipo imagen, con el código de las líneas siguientes

label1.Text += rm.GetString("query1"); 
System.Drawing.Bitmap bitmap = (System.Drawing.Bitmap)rm.GetObject("pugme");

Por último únicamente se guarda la imagen en el directorio de la aplicación para crear un objeto Pixbuf el cual se dibujará en un control DrawingArea, esto ocurre en las siguientes líneas:

bitmap.Save("pugme.png",System.Drawing.Imaging.ImageFormat.Png);
pngbuf = new Pixbuf("pugme.png");

Los métodos presentados por este programa en GTK# aplican para cualquier otra aplicación .NET incluso si el lenguaje de programación utilizado no es C#.
>Compilamos la aplicación y ejecutamos la aplicación con los siguientes comandos desde una terminal:

$ mcs –pkg:gtk-sharp-2.0 –r:System.Drawing Main.cs
$ mono Main.exe


Al ejecutar la aplicación se mostrará como en la siguiente imagen:


Al presionar el botón Load resources deberán de cargarse los recursos de cadena e imagen respectivamente, antes de ejecutar la aplicación es importante verificar que el ensamblado demo.resources.dll se encuentre en el mismo directorio de la aplicación.

El resultado final se mostrará como en la siguiente imagen:

Parte del código de este programa se derivo del ejemplo 4-8 del capítulo 4 del libro Mono: A Developer's Notebook de Niel M. Bornstein y Edd Dumbill


domingo, 25 de diciembre de 2011

Entendiendo Satellite Assemblies usando MonoDevelop - (parte 1)

Una de las características más atractivas que .NET ofrece para el desarrollo de software es la capacidad de crear componentes en diferentes lenguajes de programación, esto es posible por que el objetivo de cada compilador existente para .NET es producir un assembly (ensamblado) el cual por definición es: La unidad funcional de distribución, versionamiento y de identidad de la plataforma .NET.
Además de clasificar los assemblies en Strong-Named o privados dependiendo de su instalación o en Single-File y Multi-File si contienen un archivo o varios, pueden también clasificarse en base a su contenido en donde tenemos a los ensamblados que contienen código MSIL y recursos (imágenes, traducciones o archivos de texto, etc) y a los Satellite assemblies (ensamblados satélite) que únicamente contienen recursos.
Para estos últimos ensamblados existen herramientas como Visual Studio o SharpDevelop que nos permiten hacerlo de forma automática, aunque también existe la opción de hacerlo de forma programática con las clases contenidas en el namespace System.Resources.

  • ResourceManager: Permite tener acceso a los archivos de recursos de forma programática.
  • ResourceReader: Lee los archivos binarios de recursos.
  • ResourceWriter: Escribe los archivos binarios de recursos.
  • ResXResourceReader: Lee los archivos XML de recursos.
  • ResXResourceWriter: Escribe los archivos XML de recursos.

En el siguiente programa mostramos el uso de la clase ResourceWriter para crear un satellite asembly. Abrimos MonoDevelop y creamos una solución GTK#, utilizando el diseñador de la interfaz gráfica, creamos una GUI similar a como se muestra en la siguiente imagen:


Construimos un manejador de evento para cada uno de los botones de manera que el código de la clase se vea como en el siguiente listado.

Al compilar y ejecutar el programa podemos ingresar uno a uno el nombre y el valor de la cadena o del archivo de imagen que contendrá nuestro archivo de recursos, en caso de las imágenes debemos habilitar el checkbox “Is image” además de que el archivo de imagen debe encontrarse físicamente en el mismo directorio que el programa, en las siguientes imágenes introduciremos un par de valores de prueba.




Después de ingresar el par de valores podemos generar físicamente el archivo de recursos con el botón “Build Resource”, como en la siguiente imagen:


La funcionalidad del botón “Build Resource” es crear una instancia de la clase ResourceWriter.

rw = new ResourceWriter("demo.resources")
Para después iterar en los valores de cada Hashtable,primero en el Hashtable de las cadenas en la cual utilizara el siguientel metodo:



rw.AddResource(entry.Key.ToString(),entry.Value.ToString());

A continuación itera en el Hastable de las imágenes en donde utiliza el método anterior salvo con la diferencia de convertir el valor en un objeto Bitmap.

rw.AddResource(entry.Key.ToString(),new Bitmap(entry.Value.ToString()));

Por último se utiliza el siguiente método:
rw.Generate();
Para crear físicamente el archivo “demo.resources” el cuál se creará en el mismo directorio donde se ejecuta el programa, como en la siguiente imagen:

Ahora solo falta crear el Satellite Assembly, esto puede lograrse con el compilador de .NET o bien con el Assembly Linker, para este tutorial utilizaremos el Assembly Linker, la instrucción para crear el ensamblado es la siguiente:

$ al /embed:demo.resources /out:demo.resources.dll

Utilizamos la opción /embed para incrustar el recurso en el ensamblado y la opción /out para nombrar al ensamblado resultado, este comando lo ejecutamos desde una terminal de consola como en la siguiente imagen:

Podemos observar que ahora el archivo mono.resources.dll es un ensamblado .NET válido mediante la herramienta MonoDis mediante el comando:

$ monodis mono.resources.dll

Veremos el contenido del ensamblado, como se muestra en la siguiente imagen:


Ahora ya tenemos listo el Satellite Assembly para que sea consumido por cualquier otra aplicación en .NET en la segunda parte mostraremos una aplicación para acceder al contenido del ensamblado.