Translate

31 ago 2014

Servicio DHCP y Servidor Web

El servicio DHCP (Dynamic Host Configuration Protocol), como bien indica su nombre, nos permite asignar direcciones IP a los equipos de una red de forma aleatoria. Esto es lo que sucede con los routers que tenemos en casa, que muchos de ellos nos asignan una IP por defecto para poder acceder a Internet, ahorrando al usuario normal el tener que estar configurando las direcciones, las máscaras y las puertas de enlace.

Cada router, dependiendo de su modelo, nos puede asignar direcciones desde la 0 hasta la 255, mientras que otros parten desde la 100, o desde la propiamente dicha, la 255 para abajo. No obstante, esto podemos configurarlo en las opciones propias del router para cancelar el servicio DHCP. Pero en definitiva, es eso, configura las direcciones de forma automática, voy con un ejemplo en Packet Tracer:


En este caso tenemos un router que nos dará acceso a Internet, tres equipos y un servidor cutre. Quién nos va a ofrecer el servicio DHCP en este caso será el Servidor, ya que el router que tengo ahí no es de los que contratamos para usar en casa (esto lo he explicado por alguna entrada ya, así que es eso) y por tanto no tiene servicio DHCP. Activamos además el típico ping o ICMP, y el propio protocolo que aquí estoy explicando para ver mejor cómo funcionan internamente.

No me voy a complicar mucho la vida con este ejemplo, por lo que haré una subred de la siguiente forma:

Subred: 192.168.1.32
Máscara: 255.255.255.240
Puerta de enlace: 192.168.1.33
Dirección del DNS: 192.168.1.40

Ahora, en la configuración de cada equipo señalamos que queremos asignar las direcciones por DHCP:

En principio, no tendremos ninguna dirección IP ni una máscara asignada, ya que el servidor (DNS) no nos ha otorgado ninguna, para ello tenemos que ir a su propia configuración una vez hayamos dicho en todos los equipos que queremos una IP por DHCP.

Vale, voy a explicarlo todo paso a paso. Primero debemos ir a la pestaña de la interfaz ethernet para darle la IP: 192.168.1.40 con máscara 255.255.255.240; a continuación vamos a la pestaña de DHCP y lo encendemos:

El Pool Name lo voy a dejar tal cual, ya que sería por así decirlo el nombre del servidor, yo personalmente nunca lo he tenido que tocar. La puerta de enlace por defecto (del servidor y todos los equipos afectados por el DHCP) será la 192.168.1.33 (que tendremos que asignarla manualmente en el router), dicho de otra forma, la puerta de enlace de los equipos será la del servidor. La dirección IP del Servidor DNS será la 192.168.1.40. El servicio DHCP empezará por la dirección IP 192.168.1.34 (la anterior es la puerta de enlace) con la misma máscara y el número máximo de usuarios será el restante total, es decir, 11 (la subred admite 15, y dos direcciones ya están ocupadas por las direcciones de red y broadcast, y otras dos por el servidor y el router). Y finalmente, le damos a "Save" para guardar la configuración.

Ahora, si enviamos un paquete desde un equipo cualquiera al servidor y teniendo ambos protocolos activados, podremos ver cómo se intercambian mensajes entre los equipos y el servidor, pues este último les está asignando direcciones IP. Y por último, si queremos ir desde un equipo al router, nos lo va a permitir también.

Hasta aquí va todo bien, pero, ¿qué es eso de DNS y Servidor Web? Bueno, los Servidores son ordenadores mucho más grandes y potentes que los normales, suelen ir en armarios de racks y necesitan de mucha refrigeración. Así pues, su coste suele ser muy alto y necesitan un mantenimiento constante, porque están las 24 horas del día encendidos (excepto cuando surgen problemas). Los servidores son tan potentes que nos permiten además del DHCP, poder incluir páginas web, así es.

Sobre el DNS (Domain Name System), es básicamente una forma de traducir las direcciones IP en nombres que las personas podamos entender. Por ejemplo, un DNS consigue que la dirección IP: http://173.194.41.242/ ; se transforme en http://www.google.com ; y esa dirección IP es la dirección de un servidor que tiene la página web de Google (un servidor web). Vamos a ver un ejemplo en Packet Tracer:


Añadimos otro servidor después de quedarnos en la quiebra tras su compra, y hacemos lo mismo que con los equipos, es decir, le decimos que obtenga sus datos por DHCP, a lo que el servidor de arriba responderá. Ahora bien, en el servidor web hay una pestaña de HTTP, donde van las páginas web:


Esa es la página que tiene por defecto el servidor web (y el servidor DHCP; es la página web que traen los servidores de Packet Tracer, pero bueno, seamos realistas esta vez xD). Y si queremos que de los ordenadores se pueda acceder a dicha página, ¿tenemos que escribir la dirección IP desde el navegador (por ejemplo, Google Chrome)? Es una posibilidad, pero como los usuarios normales no van a saber su dirección IP (y que este DHCP es dinámico: ahora a mí me ha dado al servidor web la dirección 37, pero mañana puede ser la 43), tendremos que indicar desde el servidor DHCP cual es el equipo exacto al que queremos enviarle paquetes para cuando queramos acceder a la página web:


En la propia pestaña de DNS nos permite configurar esto, transformando la dirección IP del servidor en un nombre, en este caso: www.ejemplo.com; Si ahora intentamos acceder desde un ordenador cualquiera de la red a la página web con el navegador, ¡mirad qué sorpresa!


Desde el primer portátil que he pillado, he ido a Desktop y a Web Browser (Google Chrome o Firefox), y he escrito: www.ejemplo.com; Me ha tardado lo suyo (¡tened paciencia!), pero finalmente vemos cómo ha podido acceder hasta la página web ubicada en el Servidor Web, todo porque el servidor DHCP ha transformado la dirección del web en un nombre. Bien podríamos haber alojado la página web en el propio servidor DHCP, solo hubiésemos tenido que indicar que la dirección IP: 192.168.1.40; era la de www.ejemplo.com, la cual contendría los ficheros .html que contienen la página.

Y por ahora nada más que añadir, ¡un saludo! =)

25 ago 2014

Programación en C [Parte 2]

En esta entrada hablaré más sobre los distintos formatos que podemos usar para tabular o para dar saltos de línea. Así como los tipos de datos, qué son las variables y cómo podemos usarlas.

Vamos primero con los los tabuladores y los saltos de línea. La tecla del Tabulador (situada encima de las mayúsculas, para quién no lo sepa), se representa con el formato de: \t; mientras que los saltos de línea se representan con: \n; veamos el siguiente código fuente de mi fichero "formatos.c":

La primera línea es un comentario, iniciado por las barritas dobles, esto indica que ese comentario será solo de una línea, y no de varias como los comentarios que usan los asteriscos. El include, me permite insertar en el programa una librería llamada "stdio.h", en la cual se recopilan numerosas funciones y código para que podamos usarlo. Y en la función main, la función principal (el programa en sí), se ejecuta un printf que saca por pantalla el texto amarillo, el cual sacará por pantalla lo siguiente, literalmente:
..1
    ..2
        ..3
¿Pero cómo es posible que haga esto? Por los formatos de tabulación y salto de línea que hay incluidos dentro del texto. El printf, y el programa en sí, van ejecutando línea a línea y letra a letra, después del primer número, hay un "\n\t", lo cual indica que salte hacia abajo y escriba el texto separado del margen. Así con lo demás, no tiene mucho misterio. Compilamos el programa con: gcc formatos.c -o formatos.out; y no recibiremos ninguna advertencia esta vez (no como en la primera parte), porque la librería ya contiene el printf y al acceder a ella, puede usarlo sin problemas. Es como si al incluir el stdio.h, estuviésemos incluyendo todo el código que trae consigo, donde se encuentra el printf. Una captura de pantalla deja las cosas más claras:

El siguiente punto son las variables. ¿Qué son las variables? Pues son datos, letras o nombres que contienen datos (explicado de forma cutre, vaya xD), y son de un tipo concreto. Pueden ser letras, cadenas de texto, números... Los tipos de datos existentes en C son los siguientes:

char: indica que la variable contendrá una sola letra, sea la que sea. También puede ser un número, pero no se podrá operar con ella; es, básicamente, texto.

int: indica que la variable será un número comprendido entre 0 y 255. Por lo general y por regla obvia, estas variables están destinadas a las operaciones matemáticas, y tienden a cambiar su valor o cambiar el de otras.

float: no obstante, el tipo de dato anterior tenía como máximo hasta 255 números, ¿qué pasaría si en un momento necesitamos un valor mucho mayor? Pues para eso se ha generado el tipo de dato flotante, que soporta números negativos, positivos y decimales de gran tamaño. Exactamente, comprende un rango desde -3.2x10^+-38 hasta +3.2x10^+-38.

Hay más tipos de datos, pero por lo general estos son los básicos y los necesarios. Ya iré explicando más sobre la marcha, pero no en esta entrada.

Para definir una variable es suficiente con seguir el siguiente esquema: tipo de dato identificador = valor:

Podemos incluso definir numerosas variables en una sola línea separándolas con comas. Pero no hay que olvidar tampoco que estas son variables locales, es decir, solo funcionan dentro de la función main, en otra zona del programa no existirían y sería necesario volverlas a declarar. Hay varios métodos para pasar variables locales (o sus valores) a través del flujo del código, como accediendo a su zona de memoria y coger lo que contiene y pasarlo a otra función, pero para ahorrarnos tantas complicaciones, podemos simplemente hacer variables globales, las cuales se definen encima de main y bajo las librerías, y como su nombre indica, al ser globales para todo el programa, funcionan en cualquier parte:

Lo que estamos haciendo con esto es definir una variable global, que será para todo el código un cinco, y dentro de main una variable char que es una letra A mayúscula, así como dos variables numéricas (dos y tres, respectivamente), y la variable x, que valdrá 2.5 (un número decimal).

Ahora bien, vamos a ver cómo sacar por pantalla el valor de estas variables, así como utilizarlas u operar con ellas. Cada tipo de dato contiene además un formato concreto a la hora de usarlo en un printf, como los tabuladores y los saltos de línea de arriba, no obstante, los formatos son diferentes. El tipo de dato char usa el formato "%c", el tipo de dato int usa el formato "%d", y el tipo de dato flotante usa el formato "%f". Hagamos un printf y veamos la prueba:

La sentencia del printf es la siguiente: printf("La variable 'ch' es:\t%c\nLa variable 'a' es:\t%d\nLa variable 'b' es:\t%d\nLa variable 'x' es:\t%f\n", ch, a, b, x);

Hay que darse cuenta que después del texto va una coma con las variables que usará, en orden de aparición, el primer "%c" corresponde a 'ch', el segundo %d corresponde a 'a', y así. Veamos qué sale por pantalla:

Pero, uy, ese número decimal es muy grande, para remediar esa cantidad de ceros hay que escribir el formato del número flotante de la siguiente forma: "%.2f", de esta manera solo saldrán dos decimales.

Respecto a la variable global, voy a comprobar ahora cómo se comporta haciendo una sencilla suma:

Lo cual saca por pantalla:

Vemos como de un printf a otro no parecer haber diferencia, pero entre ambos, en el código fuente, vemos que hay una suma que incrementa a la variable global su propio valor con el de 'a' y 'b', lo cual resulta en diez (sí, he cogido esos valores a propósito, ¡odiadme!).

Los operadores los dejaré para otro momento, y pensad que la utilidad de las variables globales puede ser para almacenar contraseñas, donde el valor queda registrado. Y tampoco olvidéis compilar cada vez que modifiquéis el código fuente, aunque creo que esto resulta obvio.

Hasta más ver~

23 ago 2014

Programación en C [Parte 1]

Bueno, hace ya un tiempo que no toco el lenguaje C, y para no dejarlo en el olvido me he decidido por elaborar una especie de "tutorial" o "guía" donde quien quiera aprender pueda seguirme y aprender cositas ^^

Lo primero, es que voy a usar software específico, basado en la licencia GPL (GNU Public License), o dicho de otra forma, software libre y gratuito. Este software será concretamente Virtual Box, primero porque uso Windows 8.1 y no quiero destinar espacio del disco duro a particiones para arranques duales, ni quiero borrar todos los datos que tengo aquí ni hacer copias de seguridad ni nada de nada, por lo que la mejor herramienta para mí es emular Ubuntu desde una máquina virtual. Ubuntu es un sistema operativo basado en Unix (sistema basado casi en su totalidad en lenguaje C, por lo que es idóneo para programar en este lenguaje), y de software libre también, que se puede descargar desde la web oficial.

No entraré en detalles sobre cómo usar Virtual Box, que creo que es bastante intuitivo: elegir sistema operativo, crear un disco virtual, darle X espacio de nuestro disco duro real, y encender la máquina colocando la ISO de Ubuntu que hemos descargado. Y pasaré directamente a la parte en la que empezamos a programar (qEmoción!).

En primer lugar, me situaré en la terminal o consola del sistema, desde donde me moveré a un escritorio concreto donde haré todos los programas. Para usar la consola, hay que buscar el XTerm (o yo al menos uso este), y dentro, si empleamos en comando pwd, podremos ver que estamos en nuestra carpeta de usuario, si hacemos ls -l, veremos que tenemos acceso al escritorio, y por tanto, nos movemos a este con cd ./Escritorio. Me gustaría hacerlo todo con permisos de root, o administración, por lo que ejecuto un sudo su, introduciendo mi contraseña de usuario para acceder.

Comprobaremos que tenemos los permisos de administración porque el símbolo de dolar ($) cambia a una almohadilla (#), evidentemente, todo lo que creemos teniendo estos permisos no lo podremos borrar luego manualmente desde el escritorio usando el ratón. Una vez tengo los permisos, creo la carpeta llamada, pues no sé, tutorialC, así tal cual, y me moveré dentro para empezar a crear mis programas:

A continuación, crearé el primer programa en C con un editor, bien puedo utilizar gedit, que es más gráfico y más simpático, pero tampoco me convence del todo, prefiero utilizar nano, y quién se aventure con el vi, ¡adelante!. En mi caso solo he tenido que escribir: nano introduccion.c, para aparecer en el editor. Los ficheros de este lenguaje utilizan el formato ".c", y gracias al editor podremos escribir lo que deseemos.

Ahora bien, vamos con la estructura de un programa en C: todo programa debe tener una cabecera donde introducir o declarar las librerías que queremos usar, las librerías son un conjunto de código que se repite mucho y para no estar volviendo a inventar la rueda, se almacena en ficheros llamados "librerías" (o "bibliotecas", vale); a continuación hay que declarar la función "main", es decir, la función o rutina principal del programa. Hay que tener en cuenta que todo programa escrito en C requiere de una función "main", la cual es el programa en sí, pues cada vez que se ejecuta dicho fichero ".c", se ejecuta el main y ya está, ignorando el resto del código. Pero claro, ¿qué es una función, preguntarás? Una función es un trozo de código que hace algo bajo un identificador (un nombre), por ejemplo, mostrar algo en pantalla, recoger datos, etc. Hay que estructurarse la cabeza y resolver los problemas en base a lo que queremos, independientemente de cómo sea el lenguaje de programación y su sintaxis, lo más importante es saber lo que se quiere hacer. Y dentro de una función, primero se declaran las variables, que son datos de un determinado tipo (por ejemplo, la variable llamada "edad" tiene el contenido "14", y es un número), y debajo de las variables, el resto del código que utiliza las mismas.

Como esto es un tutorial, dejaré una breve captura de pantalla de cómo es un programa básico en C y la estructura que sigue:

Bien, iré parte a parte:
/*Programa de ejemplo*/: esta línea indica que hay un comentario; un comentario de este tipo (que abarca una o varias líneas) va siempre entre "/*" y termina con "*/", y son, como bien dice su nombre, comentarios para ayudar a los programadores, frases que el compilador ignora y no ejecuta. Imaginad que en un videojuego puede haber miles de líneas de código, y para ayudarse entre sí los programadores del juego van escribiendo comentarios para indicar qué hace cada parte del programa y no olvidarlo.

main(){}: es la famosa función principal, el programa en sí. La estructura que sigue es el identificador (main en este caso), los paréntesis que tienen una utilidad que no voy a comentar en un tutorial, ahora mismo están vacíos y no hacen nada, y los corchetes, que contienen todo el código de la función. Cada vez que ejecutemos el programa, se ejecutará lo que haya dentro de los corchetes, es decir, dentro de la función main().

printf();: printf(), al igual que main(), es una función, pero ya está predefinida y el sistema la entiende y la ejecuta, dentro de los paréntesis se introduce un texto que va entre comillas dobles y el cual es "¡Me encanta el lenguaje C!". La función printf lo que hace es sacar en pantalla este texto.

\n: este símbolo se encuentra dentro de la función printf(), y va al final. Lo que hace es que en esa parte del texto, haya un salto de línea.

exit(0);: exit() es otra función, indica que el programa termine, no obstante, cuando la función main() alcanza su última línea termina, por lo que aquí es un poco inútil, ya que está de relleno. El cero que se le introduce a la función tampoco lo explicaré aquí.

Y los más ávidos os habréis percatado de que cada instrucción debe terminar en punto y coma (printf y exit).

En definitiva, el programa lo que hace es sacar en pantalla una frase. Lo siguiente ahora es guardar su contenido y volver a la terminal, desde donde lo compilaré para crear un nuevo fichero ejecutable:

He compilado el programa con: gcc introduccion.c -o introduccion.out. Con esto le estoy diciendo al compilador "gcc" que compile el fichero "introduccion.c" en otro llamado "introduccion.out". Esto lo que hace es coger el código fuente del primer fichero y, propiamente dicho, compilarlo para crear el programa. Ahora, si ejecutamos el ".out" (el programa), veremos que se ejecuta sin problemas a pesar de las advertencias que nos haya sacado en la compilación, lo hacemos así: ./introduccion.out:

Y vemos que efectivamente, sale en pantalla el texto de "¡Me encanta el lenguaje C!". Si por algún motivo no tenéis el compilador, basta con hacer un simple: apt-get install gcc. De esta forma lo descargará y estará disponible. GCC es el compilador oficial de C (transforma el código fuente que hemos escrito en un programa).

Y si ahora editamos el fichero ".out", nos encontraremos con una sorpresa... y eso lo dejo a vuestra curiosidad, un saludo =)

22 ago 2014

Análisis random sobre Pokémon

He decidido desligarme un poquito (mucho) de la temática de mi blog durante un momento para hablar sobre una de las sagas de videojuegos que más me han marcado desde mi infancia. Todavía recuerdo cuando tenía cinco añitos y vi por primera vez, al llegar del colegio, encima de la mesa del salón de mi casa una Game Boy Color con el juego de Pokémon: Edición Azul.

Podría definir ese primer momento como mágico, y recuerdo cómo la saga no pasó desapercibida: muchos compañeros de clase y niños jugábamos a aquellos juegos tan especiales que, para ser de 8 bits (ridículo con los videojuegos actuales), hizo nuestras infancias de algo especial. Pero ahora, pensando sobre esto, no puedo evitar pensar que eso no dejaba de ser una simple moda como las demás, no obstante, lo que ayudaba a esa "moda" a mantenerse era la cantidad de contenido que teníamos en España sobre la saga: tazos, series de dibujos animados, juguetes, etc.

Con el tiempo y el cambio de generación, mucha gente terminó desligándose de la saga, ya fuese porque gran parte de esa publicidad se perdió y no supieron mantener la esencia en las nuevas generaciones que llegaron, o porque el salto entre alguna que otra generación les pareció muy brusco. Me he encontrado en persona muchísimas personas de este tipo, gente que se quedó anclada en la tercera generación (comprendida por Zafiro, Rubí, Esmeralda, Verde Hoja y Rojo Fuego, entre otros), alegando que la saga alcanzó su clímax hasta el Esmeralda o los remakes, y a partir de ahí se perdió por completo la esencia. No hablemos también de la gente que tiene en mente por alguna absurda razón que Pokémon es sinónimo de algún calificativo ofensivo (gente que, sin duda, también me he encontrado hasta debajo de las piedras).

Esto me ha hecho pensar, y es cierto que yo también sentí cierto cambio a partir de la tercera, sobre todo en los diseños de los Pokémon, los cuales a mi parecer, algunos rompen bastante con lo que veníamos acostumbrados a ver, acercándose en algunos casos a Digimon, la principal saga antagonista de Pokémon. Así mismo, también llegué a sentir que muchas partes del juego terminaban siguiendo el mismo hilo: reunir ocho medallas, combatir contra pescadores que utilizaban equipos de seis Magikarps, derrotar a los malos, capturar al legendario y ganar la Liga. Eso me desmotivó un poco, a pesar de que profundizaron mucho en la historia de Pokémon creando los Pokémon originales (Dialga, Palkia, Giratina y Arceus), los primeros que existieron y crearon el universo vamos, cosa que igualmente me sigue gustando.

Pero el hecho de que siguieran el mismo camino me resultó algo desmotivante, cosa que mejoró muchísimo con la quinta generación (Blanco, Negro, Blanco 2 y Negro 2), cuyas primeras versiones introdujeron una historia muy profunda y llena de giros inesperados: la primera vez en la saga que vi algo así, haciendo de esta (por muchas más razones) mi generación favorita. Las segundas versiones de la quinta siguieron el mismo hilo de siempre, pero se introdujeron tantas posibilidades nuevas en el gameplay que no me importó, de hecho, se me hizo bastante entretenido jugar al Negro 2.

De algún modo, fue gracias a Pokémon: Edición Negra 2 cuando me introduje de lleno en el mundo competitivo de Pokémon, y es aquí donde empecé a ver la saga de forma muy, muy diferente. Un videojuego donde no solo importaban los gráficos, la historia, o si la banda sonora es bonita o no, sino un juego competitivo, estratégico y muy entretenido. Me di cuenta entonces que la gente que no tenía ni idea de competitivo, juzgaba siempre la saga en base al diseño de los Pokémon o su historia, o incluso su dificultad, la cual a mi parecer, sigue bastante descompensada.

La brecha entre ambas categorías es tal, que muchos Pokémon aparentemente inútiles, así como incontables movimientos inútiles durante en transcurso normal del juego, se vuelven muy importantes a la hora de luchar en competitivo. Es normal que en la primera generación todo el mundo utilizase Trueno, Terremoto y Rayo hielo contra todos los enemigos, porque apenas había movimientos: el tipo Dragón solo tenía un movimiento de daño fijo (Furia Dragón, que bajaba siempre 40 PS), y encima era débil al hielo (un tipo inútil el Dragón), o el tipo Fantasma, que solamente poseía dos movimientos (Tinieblas y Lengüetazo, y en ambos casos la potencia era escasa). La compatibilidad de tipos se volvía un poco caótica también cuando se decía que los Fantasmas eran débiles a los Psíquico por culpa de Gengar, el cual es también Veneno y de ahí su debilidad a Alakazam. Incluso he conocido jugadores que ni se dignaban en mirar las estadísticas de sus Pokémon, las cuales han ido variando con el tiempo a mejor, añadiendo el Ataque Especial y Defensa Especial, o los IVs, o los EVs.

Tras todo esto, he terminado viendo que la saga es tan profunda como uno quiere que sea, no me parece justo que mucha gente critique a Mega-Slowbro o Mega-Salamence, parodiando su diseño con el tipo ficticio "Comida", cuando desde los inicios hemos tenido a Exeggcute. O que esta misma gente critique la saga entera por Pokémon como Garbodor, cuando en la primera generación teníamos a Magnemite o Grimer; o en la segunda generación apenas se incluyesen Pokémon y los únicos interesantes apareciesen después de la Liga, en Kanto; o que los objetivos de los Team Aqua y Magma fuesen absurdos y ridículos, como crear un mundo sin agua o un mundo solamente de agua; o que hasta la cuarta generación se pudiese paralizar a un Pokémon eléctrico (¿¡en serio!?).

Yo me he quedado anonada con esto, sobre todo las últimas semanas donde no he parado de ver críticas a todas las nuevas noticias que salen de Game Freak. Porque alguien que no sabe de competitivo, no sabrá casi nada de Pokémon, y es así. Los juegos a mi parecer, al menos hasta la cuarta generación, son aburridos a más no poder por la dificultad, donde de derrotar a cientos de entrenadores fácilmente con un solo movimiento debido al nivel de tu Pokémon, te encuentras en el Frente de Batalla y te crujen por todas partes ya que estas zonas están orientadas a los combates, no al nivel del Pokémon y a una historia bonita.

Por eso, creo que antes de decir que la saga de Pokémon va a peor porque ya no saben que inventar, o solo quieren dinero y los juegos duran poquísimo, me gustaría que se viese más en profundidad la esencia de los combates Pokémon. Mega-Slowbro en competitivo ya no es tan feo, ¿cierto? Pues es así, y lamentablemente, jugando a los juegos es muy difícil aprender de esto, no obstante, yo los seguiré jugando siempre que pueda, porque me lo paso bien.

Y hasta aquí, las paranoias de una fan empedernida de Pokémon. ¡Un saludo, entrenadores!

VLAN y Encapsulamiento Dot1Q

VLAN significa Virtual LAN, es decir, una red local virtual. Nos ayuda mucho a la hora de dividir la red sin necesidad de subredes, aumentando de esta forma la seguridad interna de esta. Por ejemplo, si tenemos una oficina y dentro de la misma red no queremos que ciertos equipos tengan conexión con otros, lo ideal es implementar una vlan.

Para ello, solo tenemos que configurar ciertos parámetros en el Switch y en el Router, vamos allá:

  • La red será de clase C, una sencilla 192.168.1.0 con máscara 255.255.255.240.
  • El PC0 tendrá la dirección 192.168.1.2 y formará parte de la vlan 1.
  • El PC1 tendrá la dirección 192.168.1.3 y formará parte de la vlan 1.
  • El servidor0 tendrá la dirección 192.168.1.4 y formará parte de la vlan 2.
  • El servidor1 tendrá la dirección 192.168.1.5 y formará parte de la vlan 2.
  • La puerta de enlace será la 192.168.1.1.

Si lo hemos hecho correctamente, todos los equipos tendrán conexión entre sí, formando de esta forma una LAN cualquiera. No obstante, al crear dos vlan distintas (1 y 2, respectivamente), estaremos separando los equipos de sobremesa de los servidores: imaginad por ejemplo que los servidores necesitan comunicarse para hacer copias de seguridad en caso de que uno falle, pero los equipos no tienen acceso a estos. Para implementar pues, las redes virtuales, es suficiente con ir a la configuración del Switch e ir puerto a puerto definiendo la misma (que dependerá de si el puerto está conectado a un sobremesa o a un servidor):

Primero definimos las vlan (cabe destacar que, la vlan 1 es la que viene por defecto y todos los equipos por defecto están en ella, de ahí a que siempre tengan conexión gracias al Switch):

Accedemos a las interfaces, como la vlan 1 viene por defecto (todos ahora mismo están en esta), basta solamente con decir que los servidores están en la segunda:

Por último, comprobamos que todo está configurado correctamente:

Utilizamos el comando: Switch#show vlan; para ver toda la información sobre las redes virtuales. Nos dice que todos los puertos por defecto están en la vlan 1, la cual se encuentra activa, excepto los puertos que conectan con los servidores, los cuales pertenecen a la segunda (activa también). Si ahora enviamos paquetes ICMP (o ping) desde un sobremesa a un servidor, nos dará error; y viceversa. Ya que por defecto, el Switch enviará los paquetes a los equipos de la misma vlan y, como no contienen la IP de destino (la dirección del sobremesa, en este caso), nos dará fallo. Esto mismo sucederá también con la puerta de enlace, a la cual los servidores no podrán acceder debido a la vlan, pues el puerto del router se encuentra en la primera por defecto.

Podemos solucionar esto último indicando con los siguientes comandos que ese puerto se comporte de forma troncal:
Switch>enable
Switch#configure terminal
Switch(config)#interface FastEthernet0/3
Switch(config-if)#switchport mode trunk

Si volvemos atrás con "exit" y empleamos el "show vlan", veremos que este puerto ha desaparecido de las lan virtuales, no obstante, todos los equipos podrán acceder al router (si empleamos por ejemplo el protocolo ARP, veremos que ya no envían solamente paquetes a los equipos de su propia vlan, sino al router también). Podemos emplear el comando:
Switch#show interfaces trunk

Para comprobar los parámetros de la interfaz. Sin embargo, nos podemos encontrar con otro problema y es que, cada interfaz troncal tiene una vlan nativa por defecto, que podemos modificar con el comando
Switch(config-if)#switchport trunk native vlan [Número de la vlan o ID]

Al configurar la vlan nativa, nos encontramos con que no podemos enviar paquetes por ese puerto desde vlans que no sean la propiamente dicha; la nativa. Podemos modificar esta para que los servidores o los sobremesa puedan acceder al router, o viceversa, pero tal y como está el diseño, nos daremos cuenta de que los sobremesa no pueden acceder al router al mismo tiempo que los servidores. Para solucionarlo, el mejor método es utilizar subredes y luego dividir estas en distintas vlan. Lo que haríamos posteriormente en el router sería dividir la interfaz de la puerta de enlace en interfaces virtuales (teniendo cada una una IP correspondiente a la puerta de enlace de cada subred), y luego, encapsular los paquetes para que de una vlan, pasen a ser otra.

Veamos un ejemplo más práctico:

Seguiremos la misma lógica que al comienzo, es decir, el switch0 se encargará de la vlan1, y el switch1 de la vlan2. Las subredes, podemos utilizar cualquiera que no nos de problemas, yo por ejemplo usaré en la vlan1 la subred 192.168.0.0 con máscara 255.255.255.248 (5 equipos en total y con puerta de enlace 192.168.0.1), y la subred de la vlan2 será la siguiente subred, la 192.168.0.8 con la misma máscara y la puerta de enlace 192.168.0.9.

Las interfaces de los distintos switchs que conectan con el router o entre ellos mismos, serán interfaces troncales, y la interfaz (en mi caso) fastEthernet0/0 del router que conecta con el switch, será la que tendremos que dividir.

En resumen, una vez hayamos asignado IPs y puertas de enlace a los equipos, asignemos en los respectivos switchs las interfaces que corresponden a una vlan o a un modo troncal y comprobemos que va todo bien, es decir, que los servidores/ordenadores tengan conexión entre sí (y sus paquetes, debido a las interfaces troncales si usamos el protocolo ARP, el cual sirve para registrar direcciones MAC de los dispositivos y saber a dónde enviar la información, alcancen el switch de la vlan opuesta pero no consiga alcanzar los equipos), estaremos preparados para ir a la puerta de enlace propiamente dicha y dividir virtualmente esa interfaz.

Para dividir la interfaz de forma virtual, basta con hacer lo siguiente en el router:

Con esto le estamos especificando que acceda a la interfaz fastEthernet0/0.2 (es decir, la correspondiente a la vlan2), le decimos el método de encapsulación que queremos (esto es un protocolo con el que conseguimos que los paquetes de una vlan, "engañen" a los dispositivos para que crean que son de una vlan distinta, y así alcanzar la vlan2 desde la 1, por ejemplo), y posteriormente le asignamos la puerta de enlace.

Repetimos, evidentemente, el proceso con la interfaz fastEthetnet0/0.1, y ajustándola a la vlan1. Si ahora enviamos paquetes de una vlan a otra, veremos que por defecto estos siempre pasarán por el router (la puerta de enlace) ya que necesitan esa etiqueta del encapsulamiento para "pertenecer" a la vlan contraria, y así en la vuelta para regresar a su vlan original:


El protocolo dot1Q lo que hace, básicamente, es modificar el paquete de información que estamos enviando, o la trama, de forma que se añaden cuatro bytes concretos para modificar el formato. De esta forma, podemos combinar distintas vlan sin que una interfaz concreta se vea afectada por la vlan nativa propia de esa red. Para ello, lo mejor y lo que yo recomiendo personalmente es utilizar subredes, ya que sino, al dividir la interfaz, no podríamos asignar puertas de enlace porque se podrían solapar entre sí: si ahora añadimos la interfaz fastEthernet0/0.3 con la IP 192.168.0.13 con máscara 255.255.255.248, nos dará error debido a que esa red ya está ocupada por la interfaz de la vlan 2.

Y hasta aquí todo sobre redes locales virtuales, un saludito a todos/as~

1 ago 2014

VLSM

Las siglas de VLSM son el acrónimo de las palabras Variable Length Subnet Mask, o dicho de otra forma, Máscaras de subred de tamaño variable.

Lo que hacemos con VLSM es el proceso contrario al subnetting, donde en este último dividíamos la red inicial alterando su máscara para coger tantas subredes como deseáramos (cogiendo bits del host para la red). En cambio, con esta nueva técnica, cogemos parte de los bits de la red para el host, dividiendo de esta forma la red inicial y generando, también, subredes, pero sin desperdiciar la cantidad de equipos. En resumidas cuentas, al igual que subnetting nos permitía coger un número exacto de subredes, VLSM nos permite coger el número exacto de equipos en cada subred (sin desperdiciar direcciones), pero sin poder controlar el número exacto de subredes; a cada nueva subred, la máscara irá variando.

Vamos con un ejemplo práctico, donde lo veremos mejor:

Supongamos que tenemos la red 10.0.0.0 con máscara 255.0.0.0; lo que queremos es tener una subred inicial con al menos, 800 equipos (imaginemos una gran empresa que nos solicita direcciones IP públicas para que sus servidores sean accesibles desde la red, o mejor dicho, las páginas web alojadas en ellos). Para ello, tenemos que calcular qué potencia de 2 está más cercana a 800 de la siguiente forma:

2^7 = 128
2^8 = 256 (128+128)
2^9 = 502 (256+256)
2^10 = 1004 (502 +502)

La primera en superar las 800 direcciones, es 2^10, y la más cercana, por lo que tendremos que coger en la máscara, diez números empezando desde la parte del host, es decir, desde el final (el último byte completo que ya lo tenemos a cero, y dos bits del penúltimo byte; los más cercanos al último byte).

Con este método nos aseguramos 1004 direcciones, y alguien podrá decir: "Pero necesitábamos 800". Sí, es innegable que de esta forma desperdiciamos 204 direcciones, no obstante, para coger 800 direcciones sin hacer este método o bien tendríamos que haber creado incontables subredes, o bien en la misma red colocar los 800 equipos, que nos lo permite por ser clase A. Sin embargo, la clase A puede alcanzar hasta dieciséis millones de direcciones (2^24 = 16.277.214; veinticuatro por ser tres bytes destinados al host, es decir, veinticuatro bits).

A pesar de perder 200 direcciones, no hemos perdido una cantidad excesiva, ni hemos tenido que estar días enteros pensando subredes y máscaras hasta abarcar los 800 equipos. Y aplicando la teoría que he estado arrastrando hasta aquí, de coger 10 bits, la cosa quedaría así:

Dirección de la primera subred generada = 10.0.0.0

Máscara de subred = 255.255.252.0 = 255.255.1111 1100.0000 0000

Aquí estamos indicando que, primero, la subred será la cero, la inicial, y segundo, que hemos cogido en la máscara diez bits para el host, dejando los demás para la red y generando así la correspondiente máscara. Éste método no es aplicable, por ejemplo, a redes de clase C, porque nos obligaría a tener una máscara de una clase superior (clase B), y esto no se permite bajo ningún concepto; sería incoherente. Pero así nos ahorramos millones de direcciones y desperdiciamos solo unas pocas.

Ahora bien, ¿cómo calcularíamos la siguiente subred? Hay que tener en cuenta que todas las subredes que generemos a partir de la primera contendrán menos equipos cada vez, y la forma en la que calculamos la dirección de subred es sencilla: colocamos el último bit de la red a uno y perdemos otro del host. Voy a poner un ejemplo donde la parte en Negrita corresponde al host:

Primera dirección de subred: 10.0000 0000.0000 0000.0000 0000

Segunda dirección de subred: 10.0000 0000.0000 0100.0000 0000

Siendo la primera la 10.0.0.0 con máscara 255.255.252.0

Y siendo la segunda la 10.0.4.0 con máscara 255.255.254.0

Tenemos que observar que cada vez que cambiamos de subred, perdemos un bit correspondiente al host, indicando que tenemos menos equipos de los inicialmente asignables (1004) para la siguiente subred, y alteramos la máscara con ello.